meteorjs iron-router waitOn并用作渲染数据

时间:2014-05-10 00:14:00

标签: meteor publish-subscribe iron-router

我尝试在Template.rendered函数中获取返回的数据。

目前的代码是:

this.route('editCat', {
    layoutTemplate : 'layoutCol2Left',
    template : 'modCategoriesEdit',
    path : '/mod/categories/edit/:_id',
    yieldTemplates : _.extend(defaultYieldTemplates, {
    'navigationBackend' : {to : 'contentLeft'} 
    }),
    waitOn : function () {
         return Meteor.subscribe('oneCat', this.params._id);
    },
    data : function () {
         return Categories.findOne({_id : this.params._id});
    }
 });

在此块中,我等待Collection Document的订阅,并将文档作为数据返回。

现在我可以在我的模板中使用返回的文档,如下所示:

<template name="modCategoriesEdit"> 
    <h1>Edit {{name}}</h1>
</template>

我的问题是我必须在我的渲染函数中使用返回的数据,如下所示:

Template.modCategoriesEdit.rendered = function () {
    console.log(this.data);
}

但是这会返回&#34; null&#34;。

所以我的问题是: 如何在渲染函数中访问返回的数据?

4 个答案:

答案 0 :(得分:14)

解决方案:

只需将以下内容添加到您的iron-router route()方法中即可。

action : function () {
    if (this.ready()) {
        this.render();
    }
}

在正确加载所有模板后,将会渲染模板。

答案 1 :(得分:10)

如果您想在渲染之前等待waitOn数据准备好,则有3种解决方案:

1-为每条路线添加action挂钩

Router.map(function() 
    {
    this.route('myRoute', 
        {
        action: function() 
            {
            if (this.ready())
                this.render();
            }
        }
    }

2-全局或在每条路线上使用onBeforeAction挂钩

全局钩子的示例代码:

Router.onBeforeAction(function(pause) 
    { 
    if (!this.ready())          
        {
        pause(); 
        this.render('myLoading');
        }
    });

myLoading(或任何名称)必须是您在某处定义的模板。

不要忘记this.render行,否则当离开路线时会出现问题(当加载路线时出现原始问题)。

3-使用内置onBeforeAction('loading')挂钩

Router.configure(
    {
    loadingTemplate: 'myLoading',
    });

Router.onBeforeAction('loading');   

myLoading(或任何名称)必须是您在某处定义的模板。

答案 2 :(得分:3)

使用action挂钩检查this.ready()是否有效,但看起来正式的方法是调用以下内容:

Router.onBeforeAction("loading");

参考:https://github.com/EventedMind/iron-router/issues/679

答案 3 :(得分:3)

就像@Sean所说,正确的解决方案是使用加载模板:

Router.onBeforeAction("loading");

但如果你不喜欢它,就像我一样,我想出了这个解决方案:

Template.xxx.rendered = function() {
    var self = this;

    this.autorun(function(a) {
        var data = Template.currentData(self.view);
        if(!data) return;

        console.log("has data! do stuff...");
        console.dir(data);
        //...
    });
}

Template.currentData是被动的,所以第一次它是null,而在第二次它有你的数据。

希望它有所帮助。

- 使用Iron Router v1.0

在Meteor v1.0上测试