События изменения модели в вложенных коллекциях не стреляют, как и ожидалось

StackOverflow https://stackoverflow.com/questions/4576150

  •  14-10-2019
  •  | 
  •  

Вопрос

Я пытаюсь использовать Backbone.js в моем первом «реальном» приложении, и мне нужна помощь отладки, почему некоторые события изменения модели не стреляют, как я и ожидал.

Если я создаю коллекцию из JSON множество С сервера, затем Fetch () он с интервалами установленного, я не получаю уведомление, если изменилась отдельная модель в коллекции. Документация на основе предполагает, что такие уведомления должны быть получены. Все, что я, кажется, получаю, это обновление уведомления на каждом выборе, что бесполезно. OTOH, если я создаю модель из JSON объект С сервера, затем почувствуйте () модель с установленными интервалами, я получаю уведомление об изменении при изменении атрибута. Любые идеи?

Подробности

Моя веб -служба AT/сотрудников/{username}/tasks возвращает массив объектов задачи JSON, с каждым объектом задачи, гнездящимся в массиве JSON Subtask Objects. Например,

[{
  "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"}
  ]
}]

Другая веб -сервис позволяет мне изменить состояние определенной подзадачи в определенной задаче и выглядит следующим образом:/tasks/45002/subtasks/1/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!");
  }

});

Когда приложение запускается, я создаю экземпляры разоблачения задач (используя данные из первой веб -службы, указанную выше), привязываю слушателя для событий изменения с помощью TaskCollection и настроить повторяющуюся установку для 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);

...

Все воспроизводит, как и ожидалось в первый раз. Но на данный момент я ожидаю, что (или оба) событие изменения коллекции или событие изменения модели будет уволен, если я изменю статус подзадачи, используя мой второй веб -сервис, но этого не произойдет.

Как ни странно, я получил события перемен, чтобы стрелять, если я добавил один дополнительный Уровень гнездования, например, веб -сервис, возвращая одну модель, например:

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

Но это кажется Klugey ... и я боюсь, что я не заархивировал свое приложение правильно. Я включу больше кода, если это поможет, но этот вопрос уже довольно словес.

Мысли?

Это было полезно?

Решение

Вы слушаете события на своих задачах, а не свои подзадачи. Если вы хотите, чтобы ваша задача перевозила события для ваших подзадач, вы должны сделать что -то подобное в своей задаче. ИНТИАЛИЗАЦИИ:

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) });
});

Возможно, вы захотите обновить привязки после события обновления. Таким образом, когда событие изменения происходит на модели подзадачи, модель задачи также запустит модель изменения.

Backbone отправит событие обновления только после того, как вы не будете проинформированы об изменении конкретной модели. Посмотрите на функцию коллекции:

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