Вопрос по javascript – Backbone.js запускается дважды при добавлении коллекции

8

Я работаю с примером приложения Todosв комплекте с последней версией Backbone (0.9.2) во время изучения Backbone.js. Мой вопрос: почему приложение предназначено для двойного запуска события рендера при добавлении модели в коллекцию Todos?

Если я помещу эту строку в функцию рендеринга TodoView:

// Re-render the titles of the todo item.
render: function() {
  console.log("Rendering!");
  this.$el.html(this.template(this.model.toJSON()));

Тогда "Рендеринг!" появляется дважды в консоли. Я понимаю, что это потому, что представление связывает событие изменения модели с визуализацией представления:

initialize: function() {
  this.model.bind('change', this.render, this);

И render вызывается в addOne, который привязан к Todos & apos; добавить событие:

addOne: function(todo) {
  var view = new TodoView({model: todo});
  this.$("#todo-list").append(view.render().el);
},

Но разве это стандартная практика двойного рендеринга? Кажется, что представление должно быть визуализировано при создании (или входе в DOM), а затем снова, если базовая модель изменяется. В этом случае ничего не меняется, но render вызывается дважды.

Опять же, я только изучаю Backbone, поэтому у меня может быть базовое недоразумение, которое приводит к моему замешательству.

Ваш Ответ

2   ответа
1

Пробоватьdebug немного больше. Попробуйте связатьchange событие вwrapper method лайк:

initialize: function(){
  this.model.bind( "change", this.renderWrapper, this );
}, 

renderWrapper: function(){
  console.log( "in the renderWrapper" );
  this.render();
}

Безусловно второйrender() был сделан дляchange event bind и не по другой причине.

Вы правы. Я должен был отметить в своем вопросе, что я изначально сузил это, поставивconsole.log('Change!') вместоthis.render(), Следовательно, я был уверен, что событие изменения было запущено. jcady
5

был быстрый взгляд. Вы правы в том, что это происходит, и нет, это не стандартная практика. Причина немного неясна, так что терпите меня;)

Приложение todo использует backbone-localstorage. Когда вы пытаетесь добавить новый элемент в приложение, оно вызывает:

createOnEnter: function(e) {
  if (e.keyCode != 13) return;
  if (!this.input.val()) return;

  Todos.create({title: this.input.val()});
  this.input.val('');
},

Обратите внимание наTodos.create, Обычноcreate добавит модель в коллекцию и сохранит ее на сервере.add событие, таким образом, будет запущено. Хотя бывает, что backbone-localalstorage делает следующее наcreate:

create: function(model) {
  if (!model.id) model.set(model.idAttribute, guid());
  this.data[model.id] = model;
  this.save();
  return model;
},

Обратите внимание наmodel.set дать модели идентификатор. Это то, что вызывает (второй)change событие.

Вы можете остановить это, изменив create на do:

if (!model.id) model.id = guid();

Удалить элементыpermanently то есть. После удаления, если я обновлю, они все еще существуют. jcady
Deletimg не может быть затронут, если вы не изменили другие вещи или есть другая ошибка. Я полагаю, что в скором времени магистральное хранилище может нуждаться в хорошей уборке;)
хороший улов! .. вы также можете использовать{silent: true} чтобы избежать запуска событий.
Вы правы, вот почему происходит событие изменения. Однако изменение кода, предложенного вами, останавливает событие, но также нарушает функциональность (я больше не могу удалять элементы). Очевидно, что это не имеет большого значения с точки зрения ответа на мой вопрос, но на случай, если кто-то в будущем прочтет это, я хотел бы указать на это. jcady

Похожие вопросы