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