3

いくつかの Ember Data モデルを管理する XMPP パーサーを作成しようとしています。情報は非同期で入ってくるので、私の知る限り、アダプターのパターンにはうまく収まりません。ちょっとした情報が得られるケースが多く、これをもとにモデルを部分的にアップデートしたい。

たとえば、プレゼンス メッセージが届いた場合、ステータスの履歴を作成できるようにこれを保存したいのですが、この新しい情報で連絡先を見つけて更新したいと考えています。連絡先には、プレゼンスとは関係のない他の多くの属性がある場合があります。連絡先とプレゼンス モデルの間には 1 対多の関係があります。

現時点では、次のようなコードがあります。

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 メソッドを使用して関係が正しく構築されます。ただし、プレゼンス レコードを present_history に追加したい場合、使用setは機能しません。興味深いことに、setPresence 側を扱うときに機能します。

私はそれが可能であることを発見しました:

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

これによりオブジェクトが追加されますが、オブザーバーの更新はトリガーされません。

私は何を間違っていますか?

4

1 に答える 1

0

理論的には、関係の両側を設定する必要はありません。規則に従って、関連付けの名前を変更してみてください。

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);
  }
于 2013-05-03T19:01:18.300 に答える