Meteorjs iron-router waitOn и использование в качестве данных для рендеринга

Я пытаюсь получить возвращенные данные в моей 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);
}

Но это возвращает "null".

Итак, мой вопрос: Как можно получить доступ к возвращенным данным в отображаемой функции?

Ответ 1

Решение:

Просто добавьте следующее к вашему методу route() для железного маршрутизатора.

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

Чем шаблон будет отображаться после того, как все будет загружено правильно.

Ответ 2

Есть 3 решения, если вы хотите подождать, пока данные waitOn не будут готовы до рендеринга:

1- Добавить крюк action для каждого маршрута

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

2- Используйте крюк onBeforeAction глобально или на каждом маршруте

Пример кода для глобального hook:

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

myLoading (или любое другое имя) должно быть шаблоном, который вы где-то определили.

Не забывайте строку this.render, иначе проблема будет возникать, когда покидает маршрут (в то время как исходная проблема возникает при загрузке маршрута).

3 Используйте встроенный onBeforeAction('loading') hook

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

Router.onBeforeAction('loading');   

myLoading (или любое другое имя) должно быть шаблоном, который вы где-то определили.

Ответ 3

Использование action hook для проверки this.ready() работает, но похоже, что официальный способ сделать это - вызвать следующее:

Router.onBeforeAction("loading");

Ссылка: https://github.com/EventedMind/iron-router/issues/679

Ответ 4

Как и @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, а во втором - ваши данные.

Надеюсь, что это поможет.

- Проверено на Meteor v1.0 с Iron Router v1.0