Meteor辅助函数总是在Meteor.startup()之前调用,并且被调用两次而不是一次

时间:2016-10-17 05:30:17

标签: javascript node.js mongodb meteor meteor-blaze

在我非常简单的流星项目中,客户端辅助函数被调用两次。

项目中的三个文件是:

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();
  }
});

这是包含目录结构的完整项目: enter image description here

以下是带有控制台日志的浏览器输出: enter image description here

2 个答案:

答案 0 :(得分:1)

Meteor.startup中的代码放在客户端上并不意味着它会在任何其他代码之前运行,它不会阻止。

Helper因反应性而运行两次。它在您加载页面时首先运行,然后在您的数据库中添加文档时重新运行。

如果您想确保数据库不为空,请将您的灯具移至服务器端Meteor.startup

答案 1 :(得分:1)

实际上,正是您的日志记录行导致帮助程序重新运行。

注意:由于这是一个初学者级别的问题,我不想深入了解这里的详细信息,但我仍然会尽量准确。

TL; DR

它运行了两次,因为在首次渲染模板时您没有数据。它与服务器上的Meteor.startup()无关。

Meteor中的模板助手是 reactive computations 。这些计算是跟踪反应数据源,例如DB查询游标(例如Websites.find().count()返回的游标。

当计算中的某些内容发生变化(无效)时,计算重新运行。这是通过在幕后使用Meteor的Tracker mechanism来实现的。

您的情况会发生什么

在页面加载时,您本地客户端的集合为空。客户端订阅它们(或者,如果您使用的是autopublish包,则会自动为您创建订阅 - 对于生产应用程序来说这不是一件好事。)

这是第一次呈现模板的时候,因此帮助程序运行时会产生一组空记录,但由于你有一个被动数据源(count()调用),它会监视它

您的服务器可能一直有数据,但您的客户尚无法使用。

一段时间后,数据从订阅到达,集合被更新,并注意到被跟踪的计数现在不同,因此计算失效并重新运行帮助程序。这次客户端已经拥有数据,结果是一组5个文档。它仍然监视光标的变化。

如果您以某种方式添加新记录或删除服务器上的现有记录(例如,通过Meteor Method调用),将使发布知道它并将新数据发送到客户端。

然后将更新客户端的集合并使 count 计算无效,这将使助手中的计算无效并导致帮助程序重新运行并再次查询集合。 / p>

如果我只从助手

返回光标怎么办?

在这种情况下,Blaze(模板库)将监视光标本身(通过观察它),并且只会以更精细的方式执行所需的更改。