2016-08-09 5 views
0

Когда вы создаете модель Backbone и присоединяете событие изменения, она будет ее слушать. И событие, если вы измените их в одно и то же время (в том же заданном вызове), он запустит событие изменения количество изменений, которое у вас есть в вашей модели.Базовая модель огня только одно изменение

Итак, представьте, что у меня есть представление, которое подобно сетке с фильтрами, и оно должно обновляться каждый раз, когда я меняю фильтр.

Моя модель по умолчанию выглядит следующим образом:

defaults: { 
    filters: { 
     from: '2016-01-01', 
     to: today.format(format), 
     limit: 25, 
     page: 1, 
     cycle: 'all' 
    } 
}, 

У меня есть перехватчик для модели в представлении:

this.listenTo(this.model, 'change:filters', this.onShow); 

И каждый раз, когда я изменить фильтр я делаю:

this.model.set('filters', { 
    from: '2016-07-01', 
    to: '2016-07-31', 
    limit: 25, 
    page: 1, 
    cycle: 'currentMonth' 
}); 

Как вы видите, я изменил 3 свойства этой модели. Случилось так, что он сработает событие изменения 3 раза. Что я хочу достичь, так это то, что он меняется только один раз, даже если у меня есть 3 изменения на модели.

Является ли это выполнимым?

Заранее спасибо

+2

То, что вы описываете, запускает событие изменения только один раз. Http://jsfiddle.net/nikoshr/u254vzmb/ Обратите внимание, что вы должны обернуть ваши 'defaults' функцией, чтобы избежать совместного использования объекта' filters' http: // backbonejs.org/#Model-defaults (малые строки) – nikoshr

+0

nikoshr прямо на всех счетах. Какую бы проблему вы ни столкнулись, это не тот, который вы описываете в своем вопросе. Либо это, либо что-то еще происходит, что вы не показываете. – Louis

ответ

0

От Backbone документации:

"изменение: [атрибут]" (модель, стоимость, варианты) - когда конкретный атрибут был обновлен.

В вашем случае модель имеет один атрибут: filters. Если вы установите новое значение для этого атрибута (независимо от того, будет ли это событие object, array, int, float, string), будет запущено. Один раз и только один раз.

Если вам необходимо соблюдать модификацию значений атрибутов, вы должны написать свой собственный обработчик.

this.listenTo(this.model, 'change:filters', function(model, value) { 
    prev = model.previous('filters'); 
    if(prev.from != value.from) model.trigger('change:filters:from', model, value.from); 
    if(prev.to != value.to) model.trigger('change:filters:to', model, value.to); 
    if(prev.limit != value.limit) model.trigger('change:filters:limit', model, value.limit); 
    if(prev.page != value.page) model.trigger('change:filters:page', model, value.page); 
    if(prev.cycle != value.cycle) model.trigger('change:filters:cycle', model, value.cycle); 
}); 

и в коде:

this.listenTo(this.model, 'change:filters:from', this.onShow); 
this.listenTo(this.model, 'change:filters:to', this.onShow); 
this.listenTo(this.model, 'change:filters:limit', this.onShow); 
this.listenTo(this.model, 'change:filters:page', this.onShow); 
this.listenTo(this.model, 'change:filters:cycle', this.onShow); 
0

Я столкнулся с этой ситуацией в основном при использовании коллекции марионетка в или CompositeViews и прослушивания изменений на основной коллекции. Часто часто обновлялась более чем одна дочерняя модель, и CompositeView нужно было бы перерисовать или переупорядочить, но я не хотел повторно отображать/переупорядочивать для каждой модификации дочерней модели - только один раз, когда одно или несколько изменений происходят одновременно. Я обращался с этим с SetTimeout, как показано ниже:

var MyView = Backbone.Marionette.CompositeView.extend({ 
    childView: ChildView, 
    initialize: function() { 
     this.listenTo(this.collection, 'change', this.onChildModelChanged); 
     this.childModelChanged = false; 
    }, 
    onChildModelChanged: function() { 
     // use a setTimeout 0 so that we batch 'changes' and re-render once 
     if(this.childModelChanged === false) { 
      this.childModelChanged = true; 
      setTimeout(function() { 
       this.render(); 
       this.childModelChanged = false; 
      }.bind(this), 0); 
     } 
    } 
}); 

Это позволяет все события изменения ребенка модель активироваться до повторного рендеринга или повторного заказа. Надеюсь это поможет.

0

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

  • Слушайте пользовательское событие на модели change-filters
  • опции Pass silent : true при настройке модели.
  • Запуск пользовательского события на модели, если есть какие-либо измененные атрибуты.

 Смежные вопросы

  • Нет связанных вопросов^_^