在我非常简单的流星项目中,客户端辅助函数被调用两次。
项目中的三个文件是:
websites.js: MongoDB集合作为Model类
image_share.html :包含Blaze模板
image_share.js :包含blaze模板的辅助函数
辅助函数webSites
被调用两次,应该被调用一次。
虽然我在mongoDB
填充Websites
集合Meteor.startup()
,但该集合在第一次通话中显示0个项目,在第二个通话中显示5个。
所以问题是,为什么在Meteor.startup()之前调用辅助函数,为什么它被调用两次并在不同的调用中返回不同的值?
以下是完整代码:
websites.js:
export const Websites = new Mongo.Collection("websites");
Meteor.startup(function(){
if(Meteor.isServer){
Websites.remove({});
for(i = 0; i < 5; i++)
Websites.insert({
"x": "this is a sample text"
});
}
});
image_share.html:
<head> <title>courseraNewsAgg</title></head>
<body>
{{> websiteList}}
</body>
<template name="websiteList">
<h2 >Items: </h2>
{{#each webSites}}
<div>
{{x}}
</div>
{{/each}}
</template>
image_share.js:
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import {Websites} from "/import/websites.js";
Template.websiteList.helpers({
webSites: function(){
console.log("list size = " + Websites.find().count());
return Websites.find();
}
});
答案 0 :(得分:1)
将Meteor.startup
中的代码放在客户端上并不意味着它会在任何其他代码之前运行,它不会阻止。
Helper因反应性而运行两次。它在您加载页面时首先运行,然后在您的数据库中添加文档时重新运行。
如果您想确保数据库不为空,请将您的灯具移至服务器端Meteor.startup
。
答案 1 :(得分:1)
实际上,正是您的日志记录行导致帮助程序重新运行。
注意:由于这是一个初学者级别的问题,我不想深入了解这里的详细信息,但我仍然会尽量准确。
它运行了两次,因为在首次渲染模板时您没有数据。它与服务器上的Meteor.startup()
无关。
Meteor中的模板助手是 reactive computations 。这些计算是跟踪反应数据源,例如DB查询游标(例如Websites.find().count()
返回的游标。
当计算中的某些内容发生变化(无效)时,计算重新运行。这是通过在幕后使用Meteor的Tracker mechanism来实现的。
在页面加载时,您本地客户端的集合为空。客户端订阅它们(或者,如果您使用的是autopublish
包,则会自动为您创建订阅 - 对于生产应用程序来说这不是一件好事。)
这是第一次呈现模板的时候,因此帮助程序运行时会产生一组空记录,但由于你有一个被动数据源(count()
调用),它会监视它
您的服务器可能一直有数据,但您的客户尚无法使用。
一段时间后,数据从订阅到达,集合被更新,并注意到被跟踪的计数现在不同,因此计算失效并重新运行帮助程序。这次客户端已经拥有数据,结果是一组5个文档。它仍然监视光标的变化。
如果您以某种方式添加新记录或删除服务器上的现有记录(例如,通过Meteor Method调用),将使发布知道它并将新数据发送到客户端。
然后将更新客户端的集合并使 count 计算无效,这将使助手中的计算无效并导致帮助程序重新运行并再次查询集合。 / p>
在这种情况下,Blaze(模板库)将监视光标本身(通过观察它),并且只会以更精细的方式执行所需的更改。