Разрешение модели в Backbone.js - вызов установлен с {silent: true} и триггером события изменения атрибута? - PullRequest
1 голос
/ 30 мая 2011

У меня есть модель диаграммы, подобная этой:

//PSEUDO
chartModel = Backbone.Model.extend({
     defaults: {
         year : 1970,
         selected = ["Sweden", "Denmark"]
     }
 }

Теперь я хотел бы установить оба года и выбрал:

chartModel.set({year: 1987, selected : ["Finland"]})

Но прежде чем инициировать изменение модели, я 'Я хотел бы «разрешить» изменения в этой нестабильной модели.Поэтому я передаю значение silent: true и переопределяю метод set:

chartModel.set({year: 1987, selected : ["Finland"]}, {silent:true})

//Pseudo set override
set : function(attrs, options) {

  // Extract attributes and options.
  options || (options = {});
  if (!attrs) return this;
  if (attrs.attributes) attrs = attrs.attributes;
  var now = this.attributes, escaped = this._escapedAttributes;

  [...]

  datamanager.loadNewDataIfNeeded(oldModel, newModel, callback)

Я бы специально хотел, чтобы менеджер данных "отличал" старые атрибуты от новых, прежде чем я вызову событие изменения:

 callback : function(){
      chartModel.change();
 }

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

... Но мое представление боковой панели, которое обязательно должно измениться: выбранное не отображает?

Sidebar = Backbone.View.extend({    
    initialize: function(){
        this.model.bind("change:selected", this.render);
    }
    render : [...]
});

Мои вопросы:

  1. При ручном запуске model.change () почему не запускаются события изменения отдельных атрибутов??

  2. Действительно ли мне нужно переопределить метод набора моделей, чтобы добиться того, что я хочу («разрешение модели, когда несколько атрибутов изменяются одновременно») или есть лучший метод?

1 Ответ

1 голос
/ 31 мая 2011

Мое мнение, основанное на моем понимании того, что вы пытаетесь сделать, таково:

  • Редко или никогда не отменять заданный метод; не знаю, почему вы чувствуете, что должны делать это в этом случае.

  • Если вы вызываете метод set без {silent: true}, вы должны получить события для change: year и change: selected и change. Но объекты должны быть связаны с ними, чтобы получить их. См. Функцию привязки.

  • Если вы вызываете функцию изменения, запускается только событие изменения. События уровня атрибута не инициируются.

Похоже, вам не следует переопределять метод set и просто убедиться, что у вас есть правильная привязка к тем объектам, которые заинтересованы в изменениях этой модели. Также устраните молчание: истинный отрывок.

Вот код, основанный на вашем комментарии:

Thing = Backbone.Model.extend({

  initialize: function(attributes, options) {
    this.bind('change:a', this.calculateC);
    this.bind('change:b', this.calculateC);
  },

  canCalculateC: function() {
    return this.get('a') == someMagicalValueForA && 
           this.get('b') == someMagicalValueForB;
  },

  calculateC: function() {
    if (!this.canCalculateC()) return;
    var self = this;
    $.post('some/url', function(data) {
      var c = // extract value for c
      this.set({c: c});  // which triggers the 'change:c' and 'change' events
    });


  }
* *} Тысяча двадцать-одина); * * тысяча двадцать-дв
ThingView = Backbone.View.extend({

  initialize: function(options) {
    this.model.bind("change:c", this.render);
  }

  ...

});

, где сама модель привязывается к событиям изменения для атрибутов a и b и обрабатывает их, проверяя, может ли она вычислить c, затем делает это, а затем устанавливает значение c на основе возврата Ajax. Затем модель вызовет «изменение: с» для просмотра. Я набросал в виде сантехники, что позволило бы это.

Это непроверенный код, но, надеюсь, концептуально близкий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...