我有一个模型,Node
:
App.Node = DS.Model.extend({
parents: DS.hasMany('node', { inverse: null })
});
假设我的服务器正在发回部分树:
{ id: "A", parents: [ "C" ] }
{ id: "B", parents: [ "C", "D" ] }
{ id: "C", parents: [ "E" ] }
我想这样渲染:
A ---- C
/
B ---/
然而,当我致电B.get('parents')
时,我收到一条消息说明:
未捕获错误:断言失败:您在ID为B的“节点”上查找了“父母”关系,但未加载某些相关记录。要么确保它们都与父记录一起加载,要么指定关系是异步的(
DS.hasMany({ async: true })
)
这些都不适合我。我只想在图表中加载记录。
我最终可能想要渲染这样的东西:
A ---- C--?
/
B ---/--?
用UI元素代表不重要的父母。
有没有办法只查看关系中已加载的记录?
答案 0 :(得分:3)
很棒的问题。
目前,Ember Data未能满足此类使用案例。
您的问题有an answer但现在已经过时了:API已经更改,现在已经变为私有。
如果你足够勇敢,你可以这样做:
@FormUrlEncoded
@POST("/login.php?action=login")
void postCredentials(@Field("username") String username,
@Field("password") String password);
演示:http://emberjs.jsbin.com/qugofu/1/edit?html,js,output
此代码的问题(除了使用私有API)是从服务器获取新节点时App.Node = DS.Model.extend({
parent: DS.belongsTo('node', {inverse: 'children'}),
children: DS.hasMany('node', {inverse: 'parent'}),
childrenIds: Ember.computed(
'_internalModel._relationships.initializedRelationships.children.canonicalState.@each.ids',
function() {
var children =
this
._internalModel
._relationships
.initializedRelationships
.children;
if (!children) return [];
return children
.canonicalState
.mapBy('id');
}
),
availableChildren: Ember.computed('childrenIds', function () {
var childrenIds = this.get('childrenIds');
return this.store.all('node').filter(function(node) {
return childrenIds.indexOf(node.id) > -1;
});
})
});
属性不会自动更新。
你必须找到一种方法来做到这一点。当你这样做时,将其作为插件发布!
这个问题不让我睡觉。
我设法改进了上述解决方案:
缺点是可用节点的查找发生在组件中而不是模型中。
答案 1 :(得分:2)
正如另一个答案正确指出的那样,Ember Data很难处理这个问题。相关情况是尝试在不提出网络请求的情况下查找异步hasMany
关系的长度(计数)。问题是parents
属性本质上是一个promisified数组,它必须是某事的承诺。
除非你想深入了解Ember Data内部,否则我会放弃hasMany
并简单地将字段定义为ID数组来解决这个问题。然后,当您确实需要父对象时,请执行find
来获取它们。您可以在适配器中使用coalesceFindRequests
以确保Ember只进行一次网络调用以获取父母双方(如果您的服务器可以处理api/nodes?ids[]=A&ids[]=B
格式)。
如果您如此倾向,可以将此行为封装到序列化程序和模型的mixins中。
答案 2 :(得分:1)
目前(2016-07-03)可以使用DS.Model
's hasMany()
method:
var children = model.hasMany('children').value();