我正在尝试在我的第一个“真实”应用程序中使用backbone.js,我需要一些帮助,以调试为什么某些模型更改事件不会像我期望的那样发射。

如果我从JSON创建一个集合 大批 从服务器中,然后以设定的间隔为fetch(),如果集合中的单个模型已更改,我不会收到通知。骨干文档表明应生成此类通知。我似乎得到的只是每个获取上的刷新通知,这无用。 OTOH,如果我从JSON创建模型 目的 从服务器中,然后以设定的间隔为fetch(),当属性更改时,我确实会收到更改通知。有任何想法吗?

细节

我的Web服务在/雇员/{用户名}/任务返回任务对象的JSON数组,每个任务对象都嵌套了子任务对象的JSON数组。例如,

[{
  "id":45002,
  "name":"Open Dining Room",
  "subtasks":[
    {"id":1,"status":"YELLOW","name":"Clean all tables"},
    {"id":2,"status":"RED","name":"Clean main floor"},
    {"id":3,"status":"RED","name":"Stock condiments"},
    {"id":4,"status":"YELLOW","name":"Check / replenish trays"}
  ]
},{
  "id":47003,
  "name":"Open Registers",
  "subtasks":[
    {"id":1,"status":"YELLOW","name":"Turn on all terminals"},
    {"id":2,"status":"YELLOW","name":"Balance out cash trays"},
    {"id":3,"status":"YELLOW","name":"Check in promo codes"},
    {"id":4,"status":"YELLOW","name":"Check register promo placards"}
  ]
}]

另一个Web服务使我可以在特定任务中更改特定子任务的状态,并且看起来像这样:/tasks/45002/subtasks/1/status/status/red [旁边 - 我打算将其更改为基于HTTP的服务,但是当前的实现更容易进行调试

我的JS应用程序中有以下课程:

子任务模型和子任务集合

var Subtask = Backbone.Model.extend({});

var SubtaskCollection = Backbone.Collection.extend({
  model: Subtask
});

带有子任务集合的嵌套实例的任务模型

var Task = Backbone.Model.extend({
  initialize: function() {

    // each Task has a reference to a collection of Subtasks
    this.subtasks = new SubtaskCollection(this.get("subtasks"));

    // status of each Task is based on the status of its Subtasks
    this.update_status();

  },
  ...
});

var TaskCollection = Backbone.Collection.extend({
  model: Task 
});

任务视图以渲染项目并聆听对模型的更改事件

var TaskView = Backbone.View.extend({

  tagName:  "li",

  template: $("#TaskTemplate").template(),

  initialize: function() {
    _.bindAll(this, "on_change", "render");
    this.model.bind("change", this.on_change);
  },

  ...

  on_change: function(e) {
    alert("task model changed!");
  }

});

当应用启动时,我实例化任务汇总(使用上面列出的第一个Web服务中的数据),将侦听器绑定到“将事件更改”的侦听器绑定到TaskCollection,并设置一个重复的Settimeout以fetch(fetch()fetch()TaskCollection实例。

...

TASKS = new TaskCollection();

TASKS.url = ".../employees/" + username + "/tasks"

TASKS.fetch({
  success: function() {
    APP.renderViews();
  }
});


TASKS.bind("change", function() {
  alert("collection changed!");
  APP.renderViews();
});


// Poll every 5 seconds to keep the models up-to-date.
setInterval(function() {
  TASKS.fetch();  
}, 5000);

...

一切都按预期的是第一次渲染。但是在这一点上,如果我使用第二个Web服务更改子任务的状态,我希望(或两者都)(或两者都)(或两者都)将收集更改事件或模型更改事件被解雇,但这不会发生。

有趣的是,如果我添加了一个,我确实会开火 额外的 嵌套级别,Web服务返回单个模型,例如:

"employee":"pkaushik", "tasks":[{"id":45002,"subtasks":[{"id":1.....

但这似乎是克鲁吉...恐怕我还没有对我的应用程序进行正确的架构。如果有帮助,我将包括更多代码,但是这个问题已经相当详细。

想法?

有帮助吗?

解决方案

您正在聆听任务上的事件,而不是您的子任务。如果您希望自己的任务随身携带子任务的事件,则应该在任务中执行类似的操作。

var self = this;    
this.subtasks.bind("refresh", function(){ self.trigger("refresh:subtask")});
this.subtasks.each(function(st){ 
  st.bind("change", function(){ self.trigger("change:subtask:" + st.id, st) });
});

您可能还需要在刷新事件后刷新绑定。这样,当更改事件发生在子任务模型上时,任务模型也将触发变更模型。

骨干只能在获取后发送刷新事件,您不会被告知特定模型中的更改。查看集合的获取功能:

options.success = function(resp) {
  collection[options.add ? 'add' : 'refresh'](collection.parse(resp), options);
  if (success) success(collection, resp);
};

默认情况下将调用刷新。这是刷新功能:

refresh : function(models, options) {
  models  || (models = []);
  options || (options = {});
  this.each(this._removeReference);
  this._reset();
  this.add(models, {silent: true});
  if (!options.silent) this.trigger('refresh', this, options);
  return this;
}

它将将所有模型静静地添加到集合中(无事件),然后触发刷新事件,但不会识别更改的元素。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top