View的集合仅在console.log中工作

时间:2013-09-07 17:17:03

标签: backbone.js

对于模糊的标题感到抱歉,我不确定发生什么事情已经足够好了。

所以,这是我视图中的渲染:

  render: function () {
    var that = this;
    var template = JST['gists/index'];
    that.$el.html(template);
    console.log(['index to render', that.collection]);
    _.each(that.collection, function (gist) { // <- I set a breakpoint here
      console.log('looping');
      that.appendGistDetail(gist);
    });

    return that;
  },

`console.log(...,that.collection)正在正确记录此集合:

["index to render", child]
  0: "index to render"
  1: child
    _byId: Object
    length: 1
    models: Array[1] // <- Note one element. Saving space, but I checked it out and the model is correct
// Worth noting 'looping' is not being logged

但是前面提到的断点输出 Chrome开发工具中的范围变量显示:

that: child
  $el: jQuery.fn.jQuery.init[1]
  childViews: Array[0]
  cid: "view2"
  collection: child
    _byId: Object
    length: 0
    models: Array[0] // <- Note it's empty, just to test I also set a bp on the line above and it's the same, and when I hovered my mouse over `that.collection` from `console.log` it also said it was empty, but it logs correctly.

所以,我不确定该怎么做,甚至不知道发生了什么。

3 个答案:

答案 0 :(得分:3)

所以你在这里设置一个断点:

_.each(that.collection, function (gist) {

并看到that.collection为空但您的console.log

console.log(['index to render', that.collection]);

表明that.collection有一个模型。我怀疑你在同一时间看到两种令人困惑的行为:

  1. console.log将其参数的实时引用抛出到控制台中,它不会拍摄当前状态的快照。因此,如果console.log通话和您查看控制台之间发生了某些变化,您将看到更改后的版本,而不是您认为已记录的版本。
  2. Collection#fetch是一个AJAX调用, A 代表 Asynchronous
  3. 所以事件的顺序可能如下:

    1. collection.fetch()发起一次AJAX通话。
    2. 您说v = new View({ collection: collection })v.render()
    3. console.log被点击,对该集合的引用会被记录在日志中。
    4. 你到达断点并找到一个空集合。
    5. 服务器响应AJAX调用,并使用一个模型填充集合。
    6. 您查看控制台并找到一个包含一个模型的集合。
    7. 混乱。
    8. 解决方案是将渲染绑定到集合上的事件,并确保您的render能够以合理的方式处理空集合。

      使用console.log来帮助您调试异步事项时要小心,如果您需要一致且明智的结果,则必须自己拍摄快照(例如console.log(collection.toJSON()))。


      PS:console.log是一个可变函数,您可以根据需要为其提供多个参数:

      console.log('index to render', that.collection);
      

      此外,集合包含模型列表,但实际上并不是列表本身。因此,像_.each(collection, ...)这样的事情不会让你完全通过模型,它会让你了解一堆你可能不关心的内部属性。您想迭代模型:

      _.each(collection.models, ....)
      

      或更好,请使用built-in Underscore methods

      collection.each(...)
      

答案 1 :(得分:0)

看起来你想循环遍历模型中的每个元素。模型具有attributes属性,允许您访问数据。

如果您使用骨干模型:

_.each(that.collection.attributes, //...

如果您正在使用骨干系列:

_.each(that.collection.models, //...

答案 2 :(得分:0)

Collection还扩展了一些下划线方法 - each

that.collection.each(function (gist) {
  // ...
});

下面的代码做同样的事情,但我建议使用第一个。

_.each(that.collection.models, function (gist) {
  // ...
});