Meteor JS:访问MongoDB的时间会影响Access的结果

时间:2015-04-23 12:36:22

标签: javascript mongodb meteor spacebars

我的Meteor JS应用程序中有一个集合:

MenuItems = new Mongo.Collection('menu_items');

在我的Template Helper文件中,我访问了这个集合:

Template.admin_menu_items.helpers({

  menuItems: function(){
    //return items from DB
    console.log('inside menuItems');

    snapshot = MenuItems.find().fetch();

    console.log(snapshot);

    return snapshot;

  },
});

然后在我的html模板文件中,我称之为帮助者:

{{#each menuItems}}
  {{#each items}}
    {{this}}
  {{/each}}

{{/each}}

然后在我的Template呈现的帮助程序回调部分中,我再次访问该集合:

Template.admin_menu_items.rendered = function(){

  console.log('Template.admin_menu_items.rendered');

  var snapshotRendered = MenuItems.find().fetch();
  //
  console.log(snapshotRendered);


}

如果我刷新页面,我会得到以下输出:

inside menuItems                    admin_m...4d3e6ec (line 9)
[]                                  admin_m...4d3e6ec (line 13)
Template.admin_menu_items.rendered  admin_m...4d3e6ec (line 36)
[]                                  admin_m...4d3e6ec (line 40)
inside menuItems                    admin_m...4d3e6ec (line 9)
[Object { _id="nHZBfwAt64dwiPjCB",  items=[3]}]

我想理解和问的是:为什么在menuItems帮助器中第一次调用MenuItems.find().fetch()并在Template渲染回调函数内第一次调用MenuItems.find().fetch()返回一个空当MenuItems集合中已有文档时,[]数组已经存在???

是因为我的模板和模板帮助文件在文件层次结构中更深,因此比我的menu_item.js文件更早加载,该文件通过以下方式实例化MenuItems变量:

MenuItems = new Mongo.Collection('menu_items');

如何确保MongoDB从最初的调用或访问权限中返回正确数量的文档?

非常感谢

2 个答案:

答案 0 :(得分:1)

  

如何确保MongoDB从最初的调用或访问权限中返回正确数量的文档?

嗯,在流星精神中...... 你没有。

Meteor的全部内容都是反应性。您不希望等待以使数据到达以开始呈现。这意味着您的用户在看到某个操作之前会在空白页面上观看一段时间,因为页面会阻止渲染,等待黑暗遗忘以获取完整数据。

相反,你去反应。您执行立即执行的reactive computations,然后每次更新其中的被动数据。助手是反应计算,Meteor中的Mongo游标是反应数据。帮助程序最初运行(可能没有返回,因为数据还没有到达),然后每次都有一些新数据进入。

你必须考虑" Nope的情况,还没有数据"在编码这些反应计算时要考虑到这一点。例如,if(someCollection.findOne())会确保someCollection中至少有一个文档 在你的情况下,它可能不是很有用,因为Spacebars很好地处理游标。

答案 1 :(得分:1)

这与订阅和线上数据有关,而不是与文件的加载顺序有关。刷新页面时,先获取模板,稍后获取数据,因此操作顺序如下:

  1. 模板在没有数据的情况下开始构建自己,因此帮助程序以空数组运行
  2. 模板已完成构建和渲染,但没有数据,它也有一个空数组
  3. 数据到达
  4. 帮助程序与新数据一起被动地重新运行,并返回一个完整的数组
  5. 如果您需要渲染回调中的数据,解决方法是在数据到达之前阻止此模板运行。您可以使用等待订阅的路由器,或通过检查数据并仅在项目数不为零时呈现模板,或使用Template.subscribe函数并使用{{保护模板来处理此问题。 1}}语句,直到数据准备就绪。

    在旁注中,您可能希望在帮助器中返回if的结果而不是find(),它在find().fetch()块中的工作方式相同,但更精细Blaze可以迭代光标本身的反应性。除非你真的需要阵列。