5

有人可以帮我理解 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 效果渲染,然后系统会加载响应式数据源(消息)并再次渲染该区域!我试图阻止它渲染两次,但没有成功。该错误似乎很容易修复,但我被困在这里。我将不胜感激任何帮助!

4

2 回答 2

3

{{> Notification}}您可以用块包围模板调用{{#if}}

{{#if has_notifications}}
  {{> Notifications}}
{{/if}}

//JS
Template.foo.has_notifications = function() {
  Message.find().count() > 0;
}    

但是,由于数据不是以一体的形式到达的,因此可能会发生多次渲染模板的情况。超时可以帮助你...

于 2012-11-12T11:12:48.060 回答
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属性,因此您的模板会在数据准备好后呈现。

于 2014-03-25T07:46:28.813 回答