流星模板呈现两次

时间:2013-12-10 03:15:03

标签: meteor

我的模板在首次加载时渲染两次。我注意到这一点,因为在

Template.home.rendered = function() {
    console.log('rendered'); // => this is printed out twice
    console.log(Data.find({}).count()); // => this is initially 0, then 1 the second time
}

此外,在第一次加载时,没有可用的数据。然而在第二次加载时,数据就在那里。

有谁知道这个问题可能是什么,为什么数据只出现在第二次?

2 个答案:

答案 0 :(得分:2)

您需要找到一种在数据可用时呈现模板的方法。

使用此模板结构,if块内容(恰好是显示数据的模板)将仅在myDataIsReady助手返回true时呈现。 (因此只触发渲染回调一次,数据立即可用)。

<template name="displayData">
    <p>This is my data : {{this}}</p>
</template>

<template name="home">
    {{#if myDataIsReady}}
        {{#each data}}
            {{> displayData}}
        {{/each}}
    {{/if}}
</template>

你必须定义一个订阅句柄(Meteor.subscribe返回的一个对象)才能使用它的被动就绪方法:我们将在myDataIsReady帮助器中引用它来跟踪数据可用性,并且帮助器将自动重新运行准备好的变化状态。

Meteor.startup(function(){
    // this subscription should return your data subset
    myDataHandle=Meteor.subscribe("myData");
});

Template.home.myDataIsReady=function(){
    return myDataHandle.ready();
}

Template.home.data=function(){
    return Data.find({});
}

但这对于这么简单的任务来说非常烦人。 这就是为什么我建议使用铁路由器让事情更简单!

使用“mrt add iron-router”将其添加到项目中,然后在client / router.js和client / router.html中使用此样板代码:

Router.configure({
    loadingTemplate:"loading"
});

Router.map(function(){
    this.route("home",{
        path:"/",
        // we indicate which subscription has to be marked ready in order to load the template
        waitOn:function(){
            return Meteor.subscribe("myData");
        }
        // the result of this function will become our target template data context
        data:function(){
            return Data.find({});
        }
    });
});

<template name="home">
    {{#each this}}
        {{> displayData}}
    {{/each}}
</template>

<template name="loading">
    <p>Data isn't ready yet...</p>
</template>

正如您所看到的,Iron Router允许我们在第一个代码示例中简单地指定我们手动实现的内容(等待特定订阅呈现模板),当然我们获得免费路由,加载机制,布局管理等...

在网上搜索一个完整的铁路由器教程(我的代码未经测试,但我希望它没问题,应该让你入门),它太棒了,它最终会被合并到Meteor。

答案 1 :(得分:0)

我在/client中有一个 body.html ,在/client/templates中有一个 appBody.html ,在铁路由器中有

Router.configure({
    layoutTemplate: 'appBody',
});

两个身体模板都被渲染(并且碰巧是相同的)。显然,/client中的 body.html 需要删除。