在构建Collection之后让backbone.js运行一个函数?

时间:2012-02-03 23:20:18

标签: javascript backbone.js backbone-events

我可能在这里完全遗漏了一些东西,但我有以下内容:

  • 一个模型,它封装了“所有”数据(从一个URL加载的所有JSON)
  • 该模型有一个(或多个)集合,它使用构建时获得的数据进行实例化
  • 我想在初始化和加载数据时在Collection上运行的一些代码

我的问题是关于合成的收藏。我可以在Collection的范围之外做到这一点,但我宁愿封装它(否则有什么意义,使它成为带有初始化器等的'类')。

  1. 我以为我可以将该代码放在initialize()函数中,但是在填充模型之前运行,因此我无法访问构成集合的模型({{1是空的。

  2. 然后我想我可以绑定到一个事件,但是在初始化之后没有触发事件。如果我从自己的端点加载了一个this.models的集合,那么我就是这样,但我没有这样做,我正在从预先存在的数据中初始化集合。

  3. 我的问题:如何在使用数据初始化后立即初始化代码以在集合上运行(即fetch不为空)。

    是否可以在不涉及“外部”代码的情况下执行此操作?

    好的,这是演示代码,也许这会更好地解释。

    this.models

2 个答案:

答案 0 :(得分:7)

不幸的是,只有在首先正确初始化并且使用silent: true标志重置模型后才会使用数据设置集合,这意味着事件不会触发。

如果您真的想要使用它,可以通过使用setTimeout(...,0)或下划线defer方法将执行任何您想要执行的操作延迟到下一个浏览器事件循环来欺骗它。

initialize: function(data, options) {

     _.defer(_.bind(this.doSomething, this));
},

doSomething: function() {

    // now the models are going to be available
}

答案 1 :(得分:0)

挖掘这个旧问题。我遇到了类似的问题,并得到了一些帮助来创建这个解决方案:

通过扩展set函数,我们可以知道集合的数据何时转换为实际模型。 (Set从.add和.reset调用,这意味着在核心函数中实例化Collection类和来自fetch,无论fetch选项中是reset还是set,都会调用它。骨干注释源和遵循功能流程帮助这里)

通过这种方式,我们可以控制何时/如何在不破解执行流程的情况下获得通知。

var MyCollection = Backbone.Collection.extend({
  url: "http://private-a2993-test958.apiary-mock.com/notes",
  initialize: function () {
    this.listenToOnce(this, 'set', this.onInitialized)
  },

  onInitialized:function(){
    console.log("collection models have been initialized:",this.models )
  },

  set: function(models,options){
    Backbone.Collection.prototype.set.call(this, models, options);
    this.trigger("set");
  }
})

//Works with Fetch!
var fetchCollection= new MyCollection()
fetchCollection.fetch();

//Works with initializing data
var colData = new MyCollection([
        {id:5, name:'five'},
        {id:6, name:'six'},
        {id:7, name:'seven'},
        {id:8, name:'eight'}
     ])

//doesn't trigger the initialized function
colData.add(new Backbone.Model({id:9,name:'nine'};

注意:如果我们不使用.listenToOnce,那么每次在集合中添加或更改模型时,我们也会调用onInitialized