【问题标题】:Meteor.js Collection empty on Client客户端上的 Meteor.js 集合为空
【发布时间】:2013-12-11 03:37:11
【问题描述】:

为什么myCollection.find().fetch() 会返回一个空数组[],即使调用是在if(data){...} 内进行的? if语句在执行console.log()之前不保证集合已经被检索到了吗?

Template.chart.rendered = function() {

        var data = myCollection.find().fetch();

        if(data) {
            console.log(data);
        }

        $('#chart').render();

}

这会在浏览器 Javascript 控制台中返回 []

【问题讨论】:

  • 问题是,为什么 Meteor 会返回空集合。我想您没有以正确的方式发布它,或者您根本不这样做。发布代码,以便我们提供帮助。
  • @Jagi auto-publish 没有被删除,并且在浏览器 Javascript 控制台中执行 console.log(myCollection.find().count()) 会返回一个正数。

标签: javascript node.js mongodb meteor


【解决方案1】:

您可以使用 count() 代替它返回结果的数量。 data 本身将是一个空数组,[] 这不是假的 ([] == true)。

也不要使用fetch(),除非您要使用原始数据,因为它非常费力。如果需要,您可以使用.forEach 循环访问它。

var data = myCollection.find();

if(data.count())
  console.log(data);

//If you need it for something/Not sure if this is right but just an example
$('#chart').render(data.fetch())

【讨论】:

  • 谢谢,不知何故,建议代码中的data.count() 会返回0,而在浏览器Javascript 控制台中执行data.count() 会返回正确的计数。所以仍然没有获取集合数据。在Template.chart.rendered 中使用rendered 以外的东西似乎可以避免这个问题,这是为什么呢?
  • 发生这种情况是因为代码运行得太早了。当流星最初加载时,没有数据进入,它会稍晚一点(大约一秒钟后)。您必须将其绑定到订阅函数,以便在呈现模板并且数据可用后触发它
  • 如果您知道自己在正确的页面上,请改用Deps.autorun
  • @Akshat 你能提到一个正确的模式来做第一种方法吗?我的情况是我需要(随机)扩展集合的一些对象,以将它们标记为轮播活动。有时 _.extends 会收到一个空列表作为 find().fetch() 的结果
  • 我明白你的意思。坚持,稍等。 :) 将链接留给其他外星人docs.meteor.com/#publishandsubscribe
【解决方案2】:

问题是您必须等待来自服务器的数据。当您只使用Template.name.rendered 函数时,它会立即被调用。您必须使用Template.name.helpers 函数来等待来自服务器的数据。 documentation 中描述了所有内容。

【讨论】:

    【解决方案3】:

    似乎当您“删除自动发布”时,您还必须在客户端上订阅。

      if(Meteor.isClient) {
        Meteor.startup(function() {
          Myvars = new Mongo.Collection("myvars");
          Meteor.subscribe('myvars')
        });
      }
    

    并在服务器上启用允许和发布

      if(Meteor.isServer) {
        Meteor.startup(function () {
          Myvars = new Mongo.Collection("myvars");
          Myvars.allow({
            insert: function () {
              return true;
            },
            update: function () {
              return true;
            },
            remove: function () {
              return true;
            }
          });
          if (Myvars.find().count() == 0) {
            Myvars.insert({myvalue:'annoyed'});
          }
    
          Meteor.publish("myvars", function() {
            return Myvars.find();
          });
        });
      }
    

    我也是新手。我只是想拥有一个所有客户都可以共享的全球价值。似乎是一个有用的想法(从初学者的角度来看)和对 Meteor 团队的完全监督,它没有以这种方式清楚地记录在案。我仍然不知道什么是allow fetch,官方文档中也完全不清楚。

    【讨论】:

    • 你可以省略== 0
    【解决方案4】:

    确实如此,但在 javascript 中你有以下奇怪的行为

    if ([]){
      console.log('Oops it goes inside the if')
    } // and it will output this, nontheless it is counter-intuitive
    

    这是因为 JS 引擎将 Boolean([]) 转换为 true。您可以了解casted to Boolean here 的不同类型。

    检查您的数组是否在开始时不为空。

    a = [];
    if (a.length){
      //do your thing
    }
    

    【讨论】:

    • data 在执行模板帮助程序代码时似乎是 [],导致集合数据丢失。但是,当在 Javascript 控制台中执行 console.log(myCollection.find().count() 时,它会显示为查询检索到的所有文档的计数。
    猜你喜欢
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    相关资源
    最近更新 更多