2012-03-16 65 views
3

我正在嘗試編寫一個XMPP分析器來管理一些Ember數據模型。信息異步進入,所以AFAIK不適合適配器模式。有很多情況下我可能會得到一些信息,並且我想基於此部分更新模型。使用Ember進行部分加載數據和關係

例如,一個存在消息到達,我想保存這個,所以我可以創建一個狀態歷史記錄,但我也想用這個新的信息找到並更新一個聯繫人。聯繫人可能有許多其他屬性與狀態無關。聯繫人和在線模型之間存在一對多的關係。

目前,我有一些代碼,看起來有點像這樣:

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

當一個新的存在消息到來時,如果沒有接觸存在,它會創建一個,並建立正確的關係使用加載方法。但是,如果我希望將presence記錄添加到presence_history,那麼使用set不起作用。有趣的是,set在處理Presence方面時確實有效。

我發現這是可能做到這一點的:

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

這增加了對象,但它不會觸發更新任何觀察員。

我在做什麼錯?

回答

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