有人可以帮助我了解Meteors模板的行为吗?
我想在我的项目中实现一个通知系统,类似于Apples Growl。 当记录写入数据库时,它使用简单的jQuery效果来显示消息。我简化了代码示例,以显示基本问题:
代码:
var Messages = new Meteor.Collection("messages");
if (Meteor.isClient) {
Template.Notification.Message = function() {
return Message.findOne({}, {sort: {seq: -1}});
};
Template.Notification.rendered = function() {
$("#livebar").fadeIn(400).delay(1000).fadeOut(400);
}
}
模板:
<template name="Notification">
<div class="row">
<div class="span6 alert alert-error" id="livebar" style="display:none;">
{{Messages.text}}
</div>
</div>
</template>
如果页面被渲染,则使用jQuery效果渲染空的不可见区域,然后系统加载反应数据源(Message)并再次渲染该区域! 我试图阻止它渲染两次,但没有成功。错误似乎很容易解决,但我被困在这里。我将不胜感激任何帮助!
答案 0 :(得分:3)
您可以使用{{> Notification}}
块围绕模板调用{{#if}}
。
{{#if has_notifications}}
{{> Notifications}}
{{/if}}
//JS
Template.foo.has_notifications = function() {
Message.find().count() > 0;
}
但是,由于数据不是一个整体,因此可能会发生模板多次渲染。超时可以帮助你...
答案 1 :(得分:3)
你需要这个额外的代码:
首先在项目内的终端上执行meteor remove autopublish
。
第二个定义要发布的内容
//On isServer
Meteor.publish('messages', function(){
return Messages.find();
});
然后订阅该数据并等待其准备好
//On isClient
subscription_handle = Meteor.subscribe('messages');
Meteor.autorun( function(computation) {
if( subscription_handle.ready() ) {
//The data is now ready, start your templates here
computation.stop(); //Stop autorun
}
});
另外,将您的集合定义为 var Messages = new Meteor.Collection("messages");
,使其成为全局变量。
完全不同(但更简单)的方法是在Iron Router中使用模板路由的waitOn属性,这样您的模板就会在数据准备好后呈现。