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