如何在模型对象上观察* all *属性更改?

时间:2012-02-08 12:55:10

标签: ember.js

我有一个从JSON对象构建的模型。

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

我希望在更新任何内容时自动保存模型。有什么方法可以为整个模型添加一个观察者吗?

编辑://添加我目前的解决方案

现在我做:

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

这是一个很大的形式,这意味着我增加了大量的观察者 - 它看起来效率很低。

Ember.sendEvent()处的萤火虫断点显示发送了名为App.model.lastName:change的事件。我可以在那里进行拦截,但希望有正式的方式。

4 个答案:

答案 0 :(得分:8)

您可以绑定到isDirty的子类的DS.Model属性。当其中一个模型属性发生更改时,isDirty会从 false 更改为 true 。它不适用于所有情况,因为它只会在重置或提交之前更改一次,但对于您的情况 -

  

我希望在更新任何内容时自动保存模型。有什么方法可以为整个模型添加一个观察者吗?

它可能正常。

答案 1 :(得分: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(),

答案 2 :(得分:2)

我有同样的要求,没有找到合适的答案,我实施了一个。

试试这个:https://gist.github.com/4279559

基本上,你想要观察的对象必须是Ember.Stalkable的混合物。您可以将该对象的属性视为'i​​tem。@ properties'(或者,如果您直接在Stalkable上烘焙观察者,'@properties'单独工作。“@ownProperties”,“@ initProperties”和“@prototypeProperties”也可以工作,并引用(实例唯一且未在任何原型上定义的属性),(定义为create()调用的一部分的属性),以及(定义为类定义的一部分的属性)。 / p>

在您的观察者中,如果您想知道更改了哪些属性并调用了处理程序,则可以使用属性“modifiedProperties”(一个数组)以及已更改属性的名称。

答案 3 :(得分:0)

我创建了一个可用作从属密钥的虚拟属性_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);
  }

});