在我的Meteor应用程序中,我有这个rendered
功能,需要访问特定的集合。假设我有一个ToDos集合
ToDos = new Meteor.Collection('todos');
if (Meteor.isClient) {
Meteor.subscribe('todos');
}
if (Meteor.isServer) {
Meteor.startup(function () {
Meteor.publish('todos', function () {
return ToDos.find({});
});
});
}
现在在渲染函数中我想做类似这样的事情
Template.todos.rendered = function () {
var todo = ToDos.findOne({...});
if (todo) {
$('[datepicker]').datepicker('setDate', todo.date);
}
}
我遇到的问题是,当调用rendered
时,todo
为undefined
,此函数仅调用一次。有没有解决这个问题? Deps.autorun
能帮忙吗?如果是,怎么样?
另一方面,如果我只能听ToDos
,我可以在那里更新日期选择器!
答案 0 :(得分:1)
是的,这是Meteor中一个可能令人讨厌的问题。基本上,虽然Meteor.subscribe
调用返回的句柄有ready
方法,它会告诉您集合是否准备就绪,通常您的rendered
回调将在返回时运行true
,所以在这种情况下它不是很有用。在某些情况下,您可以在订阅中使用onReady
回调,如果您知道模板实例存在并且可以执行任何操作,甚至可以从其他地方插入模板的数据上下文可能在rendered
回调中,但这可能是处理你出现的问题的一种非常混乱的方式(因为如果在DOM之前有一个集合 准备好的情况已被渲染它会掉下来。)
<强>解:强>
通常情况下,iron router是最好的解决方案,因为它允许每个路由都有waitOn
回调,您可以使用它来指定哪些订阅需要ready()
之前页面开始呈现(尽管您可以等待ready
回调的任何内容,而不仅仅是订阅)。这样,您始终知道,Collection.find
会在您的rendered
首次回调运行时返回您期望的内容。
答案 1 :(得分:1)
假设您有一个只有一页的简单应用
使用deps的可能实现
if (Meteor.isClient) {
Meteor.startup(function() {
Meteor.subscribe('todos');
Deps.autorun(function(e) {
var todo = ToDos.findOne({...});
var $picker = $('[datepicker]');
if (!!todo && !!$picker) {
$picker.datepicker('setDate', todo.date);
}
});
});
}
Meteor首先渲染模板,然后抓取数据。因此,当数据发生变化时,您必须设置数据选择器。
Collection.observe也可能对您感兴趣。每次添加,更改,删除数据等时都可以进行回调。
var todo = ToDos.find({...});
var handle = todo.observeChanges({
added: function (id, todo) {
// do stuff on added
},
removed: function () {
// do stuff on removed
}
});