[英]How to create computed attribute in controller based on store information and model hasMany relationship
我有一個對象“模塊”類型的模型。 簡化后,它是這樣的:
App.Module = DS.Model.extend({
name: DS.attr('string'),
orModules: DS.hasMany('module', { inverse: null }), // reflexive relship
});
在Module
的視圖中,應該有一個不是當前model
,也不包含在model.orModules
中的所有Module
記錄的列表。 我認為此信息不屬於App.Module
而是屬於App.ModuleController
。
問題在於,我仍然對DS.PromiseArray
和異步內容以及Ember
和DS
的“類”(如DS.PromiseArray
。
好,這是我的嘗試:
App.ModuleController = Ember.Controller.extend({
availableModules: function () {
var thisModule = this.get('model');
var allModules = this.store.findAll('module'); // this is a promise, right?
var orModules = thisModule.get('orModules'); // this as well, more exactly a `DS.PromiseArray`, right?
return DS.PromiseArray.create({
promise: Ember.RSVP.hash({allMods: allModules, orMods: orModules}, function (res) {
// Here I guess both promises are fulfilled, so I
// have access to all data
// But, first problem res.allMods and res.orMods have different interfaces.
// I can access res.allMods.content for the Module objects, and call mod.get('id'), but I have trouble transversing res.orMods.
// And the second and big problem is, I don't know what should I return.
// even returning some hardcoded value raises an exception
// "Assertion Failed: ArrayProxy expects an Array or Ember.ArrayProxy, but you passed object
return [{id: 666, name: '666'}];
})
});
}.property('model.orModules'),
});
因此,如您所見,我很困惑。 有什么幫助嗎? 提前致謝。
您應該同時提供路線中的當前模塊和其他模塊:
return Ember.RSVP.hash({
modules: allModulesPromise,
currentModule: currentModulePromise
});
您可以從模塊中提取當前模塊,例如:
App.IndexRoute = Ember.Route.extend({
model () {
let allModulesPromise = this.store.find('module');
let currentModulePromise = allModulesPromise.then(
// Whatever way you use to identify which module is the current
modules => modules.findBy('id', '1')
);
return Ember.RSVP.hash({
modules: allModulesPromise,
currentModule: currentModulePromise
});
}
});
有了modules
和currentModule
,過濾掉其他模塊變得很簡單:
App.IndexController = Ember.Controller.extend({
availableModules: Ember.computed(
'model.currentModule.children.@each.id',
'model.modules.@each.id',
function() {
let currentModule = this.get('model.currentModule');
let children = currentModule.get('children');
return this
.get('model.modules')
.filter( module => (
module !== currentModule
&& !children.contains(module)
));
}
)
});
演示: http : //emberjs.jsbin.com/woqofo/3/edit?html,js,output
當路由的model
鈎子返回非承諾時,路由會立即將返回的值傳遞給控制器,然后控制器將呈現模板。
但是,當model
掛鈎返回承諾時,路由將進入“加載”狀態並等待承諾解決。 當它與一個特定值解析, 則路由經過的值到控制器以呈現與該模板。
因此,您無需在控制器中處理承諾! 您已經解析了要渲染的數據。
您可以在控制器中執行Ajax請求,但是為什么要麻煩呢? 相反,您可以使用URL參數和查詢參數在URL中反映當前模型。 如果這樣做,則每當URL更改時,路由就會更新控制器上的model
屬性。
要獲取一些不屬於URL的任意數據,請使用服務。
TL / DR:避免在控制器/組件中聲明諾言(執行Ajax請求),您的生活將會更加幸福。 :d
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.