Backbone.js触发器回调绑定不能按预期工作

MrJ*_*MrJ 2 javascript backbone.js

我有一个Backbone Collection,只要另一个Backbone Model(没有Collection的一部分)发生变化就需要获取.

当我这样写:

this.fModel = new FooModel();
this.bCollection = new BarCollection();
this.fModel.on("change", this.bCollection.fetch, this)
Run Code Online (Sandbox Code Playgroud)

触发更改事件时,我收到以下错误:

Uncaught TypeError: Object #<Object> has no method 'trigger'
Run Code Online (Sandbox Code Playgroud)

但是,当我简单地包装Collection的fetch调用时,它按预期工作:

this.fModel = new FooModel();
this.bCollection = new BarCollection();
this.testfunc = function(){
    this.bCollection.fetch();
}
this.fModel.on("change", this.testfunc, this)
Run Code Online (Sandbox Code Playgroud)

为什么会这样?谢谢!

rfu*_*duk 6

这是一个有趣的尝试和解释:)

所以当你这样打电话时on:

this.fModel.on('change', this.bCollection.fetch, this);
Run Code Online (Sandbox Code Playgroud)

您正在设置fetch运行的上下文this.在这段代码中,它看起来就像this是您的顶级应用程序或类似的.fetch对此无能为力!我们来看看实现fetch:

// Fetch the default set of models for this collection, resetting the
// collection when they arrive. If `add: true` is passed, appends the
// models to the collection instead of resetting.
fetch: function(options) {
  options = options ? _.clone(options) : {};
  if (options.parse === undefined) options.parse = true;
  var collection = this;
  var success = options.success;
  options.success = function(resp, status, xhr) {
    collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
    if (success) success(collection, resp);
  };
  options.error = Backbone.wrapError(options.error, collection, options);
  return (this.sync || Backbone.sync).call(this, 'read', this, options);
},
Run Code Online (Sandbox Code Playgroud)

所以我们基本上可以做到var collection = this;...... 哎呀!

我们将collection内部fetch设置为您的顶级应用程序!


所以当你包装它时它起作用的原因更有趣:

var wrapped = function() { this.bCollection.fetch(); };
this.fModel.on('change', wrapped, this);
Run Code Online (Sandbox Code Playgroud)

我们设定的范围内wrappedthis.那很好,因为这this.bCollection正是我们想要的.但是当你fetchbCollection这里打电话时,它正在以正常方式进行,将其this内部绑定到它被调用的对象 - 这是正常的javascript东西.


所以,这是一个TL; DR:

你真的想要:

this.fModel.on('change', this.bCollection.fetch, this.bCollection);
Run Code Online (Sandbox Code Playgroud)

因为fetch函数调用的上下文应该是集合本身,而不是别的.

合理?

干杯:)