Meteor.startup()之前总是调用meteor帮助器函数,而不是一次调用
在我非常简单的meteor项目中,客户端辅助函数被调用两次。
项目中的三个文件是:
sites.js:作为Model类的MongoDB集合
image_share.html :包含Blaze模板
image_share.js :包含模板的辅助函数
助手函数webSites
被调用两次,应该被调用一次。 尽pipe我在Meteor.startup()
填充了mongoDB
集合Websites
,但集合在第一个调用中显示0个项目,在第二个调用中显示5个项目。
所以问题是,为什么在Meteor.startup()之前调用helper函数,为什么它会被调用两次,并在不同的调用中返回不同的值?
以下是完整的代码:
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(); } });
这是完整的项目目录结构:
这是在控制台日志浏览器中的输出:
事实上,这是你的logging线,导致助手重新运行。
注:我不想在这里详细讨论这个问题,因为这是一个初学者的问题,但是我仍然会努力做到精确。
TL; DR
它运行了两次,因为您在模板第一次渲染时没有数据。 它与服务器上的Meteor.startup()
无关。
meteor中的模板助手是反应式计算 。 这些计算正在跟踪被动数据源 ,如DB查询游标(例如,由Websites.find().count()
返回的数据源 。
当计算中的某些内容发生变化(无效)时,计算重新开始。 这是通过在幕后使用meteor追踪机制来实现的。
你的情况发生了什么
在页面加载时,您的本地客户端的集合是空的。 客户订阅他们(或者,如果您正在使用autopublish
包,订阅会自动为您创build – 生产应用程序不是一件好事)。
这是第一次呈现模板的时候,所以助手运行的结果是一组空的logging,但是由于你有一个被动的数据源( count()
调用),它监视它。
您的服务器可能一直有这些数据,但您的客户端尚未提供。
一段时间后,数据从订阅到达,集合被更新,并注意到被跟踪的计数现在是不同的,所以计算失效,助手重新运行。 这次客户端已经有了数据,结果是一组5个文件。 它仍然监视光标的变化。
如果添加新logging或以某种方式删除服务器上的现有logging(例如,通过Meteor方法调用),将使发布发现并将新数据发送到客户端。
然后,客户端的集合将被更新并使count计数无效,这将使助手中的计算无效,并使得助手重新运行并再次查询集合。
如果我只从帮手中返回光标,该怎么办?
在这种情况下,Blaze(模板库)将监视游标本身(通过观察它),并且只会以更细化的方式执行所需的更改。
把代码放在客户端的Meteor.startup
并不意味着它会在任何其他代码之前运行,它不会阻塞。
由于react native,助手运行两次。 它在加载页面时首先运行,然后在你的数据库中添加文档时重新运行。
如果你想确保数据库不是空的,把你的灯具移到服务器端Meteor.startup
。