Как я могу наблюдать изменения свойств * all * на объекте модели? - программирование
Подтвердить что ты не робот

Как я могу наблюдать изменения свойств * all * на объекте модели?

У меня есть модель, построенная из объекта JSON.

// extend the json model to get all props
App.Model = Ember.Object.extend(window.jsonModel);

Я хочу автоматически сохранять модель, когда что-либо обновляется. Есть ли способ добавить наблюдателя ко всей модели?

EDIT://добавление решения, которое я сейчас хожу

На данный момент я:

// XXX Can't be right
for (var prop in window.jsonModel) {
    if (window.jsonModel.hasOwnProperty(prop)) {
        App.model.addObserver(prop, scheduleSave);
    }
}

Это большая форма, что означает, что я добавляю массу наблюдателей - кажется, это неэффективно.

Точка останова firebug в Ember.sendEvent() показывает, что отправляются события, называемые App.model.lastName:change. Я мог взломать там перехват, но надеялся на официальный путь.

4b9b3361

Ответ 1

Вы можете привязать к свойству isDirty подкласс DS.Model. При изменении одного из свойств модели значение isDirty изменяется от false до true. Он не будет хорошо служить для всех случаев, потому что он изменяется только один раз до reset или совершается, но для вашего случая -

Я хочу автоматически сохранять модель, когда что-либо обновляется. Есть ли способ добавить наблюдателя ко всей модели?

он может работать нормально.

Ответ 2

Из статьи:

autosave: function(){
    this.save();
}.observes('attributes'),


save: function(){
  var self = this,
    url = this.get('isNew') ? '/todos.json' : '/todos/'+this.get('id')+'.json',
    method = this.get('isNew') ? 'POST' : 'PUT';

  $.ajax(url, {
    type: 'POST',
    // _method is used by Rails to spoof HTTP methods not supported by all browsers
    data: { todo: this.get('attributes'), _method: method },
    // Sometimes Rails returns an empty string that blows up as JSON
    dataType: 'text',
    success: function(data, response) {
      data = $.trim(data);
      if (data) { data = JSON.parse(data); }
      if (self.get('isNew')) { self.set('id', data['todo']['id']); }
    }
  });
},

isNew: function(){
   return !this.get('id');
}.property('id').cacheable(),

Ответ 3

У меня было такое же требование, и я не нашел подходящего ответа, я его реализовал.

Попробуйте следующее: https://gist.github.com/4279559

По существу, объект, который вы хотите наблюдать за всеми свойствами ДОЛЖЕН быть смешанным с Ember.Stalkable. Вы можете наблюдать свойства этого объекта как "item. @Properties" (или, если вы испекли наблюдателей непосредственно на Stalkable, "@properties" работает. "@ownProperties", "@initProperties" и "@prototypeProperties" также работают, и ссылаются на (свойства, которые уникальны для экземпляра и не определены на каком-либо прототипе) (свойства, которые определены как часть вызова create()) и (свойства, которые определены как часть определения класса).

В ваших наблюдателях, если вы хотите знать, какие свойства были изменены и вызывается обработчиком, свойство "modifiedProperties", массив, будет доступно с именами измененных свойств.

Ответ 4

Я создал виртуальное свойство _anyProperty, которое можно использовать как зависимый ключ:

import Ember from 'ember';

Ember.Object.reopen({

  // Virtual property for dependencies on any property changing
  _anyPropertyName: '_anyProperty',
  _anyProperty: null,

  propertyWillChange(keyName) {
    if (keyName !== this._anyPropertyName) {
      this._super(this._anyPropertyName);
    }
    return this._super(keyName);
  },

  propertyDidChange(keyName) {
    if (keyName !== this._anyPropertyName) {
      this._super(this._anyPropertyName);
    }
    return this._super(keyName);
  }

});