【问题标题】:Partial loads using Ember Data and relationships使用 Ember 数据和关系进行部分加载
【发布时间】:2012-03-16 15:13:54
【问题描述】:

我正在尝试编写一个 XMPP 解析器来管理一些 Ember Data 模型。信息是异步传入的,因此 AFAIK 它不适合适配器模式。在很多情况下,我可能会得到一些信息,我想在此基础上对模型进行部分更新。

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

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

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 在处理 Presence 端时确实有效。

我发现可以这样做:

...
contact.get('presence_history').addObject(this);
...

这会添加对象,但不会触发任何观察者的更新。

我做错了什么?

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

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

    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 而不是直接操作clientIdForId

    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);
      }
    

    【讨论】:

      猜你喜欢
      • 2015-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-05
      • 1970-01-01
      相关资源
      最近更新 更多