Ember.js 使用余烬数据和关系的部分荷载

Ember.js 使用余烬数据和关系的部分荷载,ember.js,ember-data,Ember.js,Ember Data,我正试图编写一个XMPP解析器来管理一些余烬数据模型。信息是异步传入的,因此很可能无法整齐地放入适配器模式中。在很多情况下,我可能会得到一些信息,并且我想在此基础上部分更新模型 例如,状态信息到达时,我想保存此信息,以便创建状态历史记录,但我还想查找并更新具有此新信息的联系人。联系人可能有许多其他与状态无关的属性。接触和存在模型之间存在一对多关系 目前,我有一些代码看起来有点像这样: Frabjous.Contact = DS.Model.extend({ primaryKey: 'jid'

我正试图编写一个XMPP解析器来管理一些余烬数据模型。信息是异步传入的,因此很可能无法整齐地放入适配器模式中。在很多情况下,我可能会得到一些信息,并且我想在此基础上部分更新模型

例如,状态信息到达时,我想保存此信息,以便创建状态历史记录,但我还想查找并更新具有此新信息的联系人。联系人可能有许多其他与状态无关的属性。接触和存在模型之间存在一对多关系

目前,我有一些代码看起来有点像这样:

Frabjous.Contact = DS.Model.extend({
  primaryKey: 'jid',
  jid:        DS.attr('jidString'),
  ...
  presence_history: DS.hasMany('Frabjous.Presence'),
});

Frabjous.Presence = DS.Model.extend({
  from:      DS.attr('jidString'),
  ...
  contact:   DS.belongsTo('Frabjous.Contact'),
  didLoad: function(){
    var contact;
    var type              = Frabjous.Contact;
    var contact_id        = this.get('from').toString();
    var contact_client_id = Frabjous.Store.clientIdForId(type, contact_id);

    if( Ember.none(contact_client_id) ){
      // No contact exists, so create one
      Frabjous.Store.load(type,{jid: this.get('from'), presence_history:[this.get('id')]});
      contact = Frabjous.Store.find(type,contact_id);
    }else{
      // Update contact
      contact = Frabjous.Store.find(type,contact_id);

      // !!! this DOES NOT work
      var history = contact.get('presence_history');
      history.addObject(this);
      contact.set('presence_history',history);
    }

    // !!! this DOES work
    this.set('contact',contact);
  }
当新的状态信息出现时,如果不存在联系人,它将创建一个,并使用load方法正确地建立关系。但是,如果我希望将状态记录添加到状态历史记录中,则使用
set
不起作用。有趣的是,
set
在处理存在端时确实起作用

我发现可以通过以下方式实现:

...
contact.get('presence_history').addObject(this);
...
这会添加对象,但不会触发对任何观察者的更新


我做错了什么?

理论上,你不应该设置关系的双方。尝试遵循约定并重命名您的关联:

Frabjous.Contact = DS.Model.extend({
  primaryKey: 'jid',
  jid:        DS.attr('jidString'),
  ...
  presences: DS.hasMany('Frabjous.Presence'),
});
然后简单地关联你的记录

if( Ember.none(contact_client_id) ){
  // No contact exists, so create one
  Frabjous.Store.load(type,{jid: this.get('from'), presence_history:[this.get('id')]});
  contact = Frabjous.Store.find(type,contact_id);
}else{
  // Update contact
  contact = Frabjous.Store.find(type,contact_id);
  this.set('contact', contact);
}
如果您不想更改JSON,您可以始终配置您的模型为您的关联指定不同的键

另外,我建议您使用
hasReferenceForId
而不是直接操作
clientdforid

Frabjous.Presence = DS.Model.extend({
  from:      DS.attr('jidString'),
  ...
  contact:   DS.belongsTo('Frabjous.Contact'),
  didLoad: function(){
    var contact;
    var type              = Frabjous.Contact;
    var contact_id        = this.get('from').toString();
    var store             = DS.defaultStore;

    if( !store.hasReferenceForId(Frabjous.Contact, contact_id) ){
      // No contact exists, so create one
      Frabjous.Store.load(type,{jid: this.get('from'), presence_history:[this.get('id')]});
      contact = Frabjous.Store.find(type,contact_id);
    }else{
      ...
    }

    // !!! this DOES work
    this.set('contact',contact);
  }