2015-08-17 62 views
1

我正在試圖定義一個計算過的屬性,它由一個已過濾的hasMany關係組成。當我循環訪問PromiseManyArray的項目時,當試圖訪問我想要過濾的屬性時,我得到undefined。在稍後調用此計算屬性時,一切正常。ember.js,在控制器中過濾PromiseManyArray

這是我的控制器代碼的簡化版本:

export default Ember.Controller.extend({ 

    availableModules: function() { 
     let thisModule = this.get('model') 

     console.log(thisModule.get('library.modules')) // This logs <DS.PromiseManyArray:ember604> 

     // loop over siblings 
     return thisModule.get('library.modules').filter(mod => { 
      // mod.classification is undefined 
      return mod.get('classification') !== 'basis' 
     }) 

    }.property('model') 
}) 

對於Module模型中,我們可以假設,它具有classification屬性,並且它屬於一個Library對象,並且Library模型hasMany模塊。

我已經試過這樣的事情,它正確地記錄屬性classification,但我不知道怎麼回事情,這樣的模板可以對其進行渲染。

availableModules: function() { 
    let thisModule = this.get('model') 

    thisModule.get('library.modules').then(mods => { 
     mods.forEach(mod => { 
      console.log(mod.get('classification')) 
     }) 
    }) 
}.property('model') 

所以,問題似乎是PromiseManyArray.filter方法裏面,找到的對象的屬性尚未得到解決......我怎樣才能建立一個承諾,將返回所有過濾的對象,一旦這些已經解決?我不知道該如何解決這個問題。謝謝。

+1

嘿所以我會做的是,而不是獲取控制器上的異步關係,而不是在其中一個模型鉤子。因此,在afterModel鉤子中獲取它們,將其設置到路由本身,然後在設置控制器中將async屬性設置到控制器上。然後在控制器中,您可以計算以過濾您的異步關係。這樣你就可以將異步關係加載到商店中,並能夠在等待加載的時候訪問加載模板。 –

+0

@布洛姆菲爾德,幫助,但我不喜歡它太多。我添加了一個答案。謝謝。 – bgusach

回答

1

受Bloomfield評論的啓發,在this thread in the ember forum的幫助下,我找到了一個可以接受的解決方案。基本上它包括解決路線中的所有關係,所以當控制器被調用時,你不必處理承諾。

解決方案:

  1. model掛鉤的路線,返回所有需要的信息
  2. 承諾的哈希定義自定義setupController,和它裏面,存儲模型和額外的數據在控制器

路由代碼如下所示:

export default Ember.Route.extend({ 
    model(params) { 
     let module = this.store.findRecord('module', params.mod_id) 

     return Ember.RSVP.hash({ 
      module: module, 
      siblingModules: module.then(mod => mod.get('library.modules')), // promise based on previous promise 
     }) 
    }, 

    setupController(controller, hash) { 
     controller.set('model', hash.module) 
     controller.set('siblingModules', hash.siblingModules) 
    }, 
}) 

注:該航線仍正常工作,{{#link-to 'route' model}}必須明確的使用屬性,就像id{{#link-to 'route' model.id}}

額外的信息

布盧姆菲爾德的做法包括使用afterModel鉤來加載額外的數據在Route對象的屬性中,然後在setupController中,將額外數據設置爲Controller。事情是這樣的:

export default Ember.Route.extend({ 
    model(params) { 
     return this.store.findRecord('module', params.mod_id) 
    }, 

    afterModel(model) { 
     return model.get('library.modules').then(modules => { 
      this.set('siblingModules', modules) 
     }) 
    }, 

    siblingModules: null, // provisional store 

    setupController(controller, model) { 
     controller.set('model', model) 
     controller.set('siblingModules', this.get('siblingModules')) 
    }, 
}) 

但是,這感覺就像一個黑客攻擊。您必須在afterModel中返回承諾,但無法訪問結果。相反,結果必須通過。然後and then stored in the路由對象...這不是一個很好的信息流。然而,這具有的優點是您無需爲模板中的鏈接指定任何屬性。

還有更多的選項,如使用PromiseProxyArray,但這對於像我這樣的新手來說太複雜了。