Частичная загрузка с использованием Ember Data и взаимосвязей

Я пытаюсь написать парсер XMPP, который будет управлять некоторыми моделями Ember Data. Информация поступает асинхронно, поэтому, насколько я знаю, она не совсем соответствует шаблону адаптера. Есть много случаев, когда я могу получить немного информации, и я хочу частично обновить модель на основе этого.

Например, приходит сообщение о присутствии, я хочу сохранить его, чтобы создать историю статусов, но я также хочу найти и обновить контакт с этой новой информацией. Контакт может иметь множество других атрибутов, которые не имеют ничего общего с присутствием. Между контактом и моделью присутствия существует связь «один ко многим».

На данный момент у меня есть код, который выглядит примерно так:

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

Когда приходит новое сообщение о присутствии, если контакт не существует, он будет создан и правильно построена связь с использованием метода загрузки. Однако, если я хочу добавить запись о присутствии в историю присутствия, то использование set не работает. Интересно, что set работает со стороной Присутствия.

Я обнаружил, что это можно сделать с помощью:

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

Это добавляет объект, но не запускает обновления ни для одного из наблюдателей.

Что я делаю неправильно?


person Theozaurus    schedule 16.03.2012    source источник


Ответы (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);
  }
person Cyril Fluck    schedule 03.05.2013