Backbone集合中消失的模型

时间:2011-10-17 22:11:38

标签: backbone.js

我有一个Backbone模型line,其中包含模型Stop的集合。 在某些时候,我想使用下划线函数reduce遍历线中的停靠点并沿着线获得总行程时间。

然而,这不起作用。似乎某些东西在某个时刻发生了变化。 它似乎只包含一个没有有意义属性的对象,尽管我知道它已经填充了四个具有有效属性的停止模型。

模特:

App.models.Line = Backbone.Model.extend({
    initialize: function() {
        var stops = new App.models.Stops({
            model: App.models.Stop,
            id: this.get("id")
        });
        stops.fetch();
        this.set({
            stops: stops
        });
        this.set({unique: true});
        this.calculateTotalTime();
    },
    calculateTotalTime: function() {
        this.get("stops").each(function(num) {
            console.log("Model!");
        });
        console.log("Unique: ", this.get("unique"));
    }
});

控制台打印输出为:

Model!
Unique:  true

应该有四个“模型!”,因为模型的数量是四个。

最奇怪的是,在控制台中一切正常:

window.line.get("stops").each(function(num) {
            console.log("Model!");
        });
Model!
Model!
Model!
Model!

JS使用Sprockets进行编译:

//= require ./init

//= require ./lib/jquery
//= require ./lib/underscore
//= require ./lib/backbone
//= require ./lib/raphael

//= require_tree ./controllers
//= require_tree ./models
//= require_tree ./views

//= require ./main

init.js:

window.App = {};
App.views = [];
App.models = [];

main.js:

$(function() {
  window.line = new App.models.Line({name: "4", id: 4});
  window.lineView = new App.views.Line({model: line});
  $("#outer").append(lineView.render().el);
});

其他一些奇怪的行为:

模型中的

console.log(this.get("stops"))产生了这个相当普通的对象:

child
  _byCid: Object
  _byId: Object
  _onModelEvent: function () { [native code] }
  _removeReference: function () { [native code] }
  id: 4
  length: 4
  models: Array[4]
    0: Backbone.Model
    1: Backbone.Model
    2: Backbone.Model
    3: Backbone.Model
  length: 4
  __proto__: Array[0]
  __proto__: ctor

但是调用console.log(this.get("stops").models),它应该产生数组,只返回一个没有有用属性的单个对象的数组:

[
  Backbone.Model
  _callbacks: Object
  _changed: false
  _changing: false
  _escapedAttributes: Object
  _previousAttributes: Object
  attributes: Object
    id: 4
    model: function (){ return parent.apply(this, arguments); }
    __proto__: Object
    cid: "c1"
    id: 4
  __proto__: Object
]

我怀疑这完全归结于对this性质的一些误解。很高兴提供任何帮助。

1 个答案:

答案 0 :(得分:6)

stops.fetch()是一个异步进程,所以你在它之后编写的代码可能会在fetch的结果从服务器返回之前触发。

你需要修改你的代码,以便在提取回来后运行所有内容。最简单的方法是使用reset集合中的stops事件:

App.models.Line = Backbone.Model.extend({
    initialize: function() {
        var stops = new App.models.Stops({
            model: App.models.Stop,
            id: this.get("id")
        });


        // store the stops, and then bind to the event
        this.set({stops: stops});
        stops.bind("reset", this.stopsLoaded, this);
        stops.fetch();

    },

    stopsLoaded: function(){
        // get the stops, now that the collection has been populated
        var stops = this.get("stops");
        this.set({unique: true});
        this.calculateTotalTime();
    },

    calculateTotalTime: function() {
        this.get("stops").each(function(num) {
            console.log("Model!");
        });
        console.log("Unique: ", this.get("unique"));
    }
});

它在您的控制台中工作的原因是因为当您输入代码来评估模型的停止时,fetch调用已经返回并填充了该集合。

希望有所帮助