Javascript 如何在EmberJS中合并(聚合)嵌套模型集合?

Javascript 如何在EmberJS中合并(聚合)嵌套模型集合?,javascript,collections,ember.js,ember-data,Javascript,Collections,Ember.js,Ember Data,以这种模式为例: Grandparent parents: DS.hasMany('parent') Parent: grandparent: DS.belongsTo('grandparent') children: DS.hasMany('child') Child: parent: DS.belongsTo('parent') 我想将一个计算属性children添加到祖父母模型中,在该模型中我需要一组children模型(祖父母.children=合并每个祖父母.pa

以这种模式为例:

Grandparent
  parents: DS.hasMany('parent')

Parent:
  grandparent: DS.belongsTo('grandparent')
  children: DS.hasMany('child')

Child:
  parent: DS.belongsTo('parent')
我想将一个计算属性
children
添加到
祖父母
模型中,在该模型中我需要一组
children
模型(祖父母.children=合并每个祖父母.parents.children)

怎么做

对于此示例数据:

Grandparent { id: 0, parents: [0, 1] }

Parent { id: 0, grandparent: 0, children: [0] }
Parent { id: 1, grandparent: 0, children: [1,2] }

Child { id: 0, parent: 0 }
Child { id: 1, parent: 1 }
Child { id: 2, parent: 1 }
我希望
祖父母.get('children')
返回ID为[0,1,2]的孩子

编辑:

App.Grandparent.reopen({
  grandchildren: function(){
    var result = [];
    this.get('parents').forEach(function(parent) {
      parent.get('children').forEach(function(child){
        console.log('is this even called?');
        result.push(child);
      });
      console.log('coz this is!');
    });
    return result;
  }.property("parents", "parents.@each.children")
});
为什么第二个循环是空的?我知道数据已加载(余烬检查器)。。那么,为什么它在这里不可接受呢

EDIT2:

App.Grandparent.reopen({
  grandchildren: function(){
    var result = [];
    this.get('parents').forEach(function(parent) {
      parent.get('children').forEach(function(child){
        console.log('is this even called?');
        result.push(child);
      });
      console.log('coz this is!');
    });
    return result;
  }.property("parents", "parents.@each.children")
});
快到了!列表似乎是空的,因为它是一个promise数组(尚未解析),因此在执行代码时,它是空的

 grandchildren: function(){
    var grandchildren = [];
    this.get('parents').forEach(function(parent) {
      var promiseArray = parent.get('children');
      promiseArray.then(function() {
        promiseArray.forEach(function(child){
          grandchildren.push(child);
          console.log(child);
        });
      });
    });
    return grandchildren;
  }.property("parents", "parents.@each.children")
所以这段代码正确地显示在控制台日志中所有的孙子。。。但是它仍然没有归还它们。这可能是出于同样的原因-当代码点击“返回祖父母”时,它仍然是空的。我现在在想,有办法解决这个问题吗

EDIT3:

App.Grandparent.reopen({
  grandchildren: function(){
    var result = [];
    this.get('parents').forEach(function(parent) {
      parent.get('children').forEach(function(child){
        console.log('is this even called?');
        result.push(child);
      });
      console.log('coz this is!');
    });
    return result;
  }.property("parents", "parents.@each.children")
});
问题的根源似乎是
DS.hasMany('parent',{async:true})
DS.hasMany('child',{async:true})
。我在原始问题中加入了异步部分,以使模型示例更加清晰

EDIT4:

App.Grandparent.reopen({
  grandchildren: function(){
    var result = [];
    this.get('parents').forEach(function(parent) {
      parent.get('children').forEach(function(child){
        console.log('is this even called?');
        result.push(child);
      });
      console.log('coz this is!');
    });
    return result;
  }.property("parents", "parents.@each.children")
});
通过从DS.hasMany中删除
async:true
,我已经解决了我的问题,并用于在没有异步的情况下正确加载它们

这修复了“空数组”(未解析的承诺数组)的问题,并允许我访问属性。然后我执行了以下代码(在模型的重新打开函数中):

而且它有效!耶

然而,我仍然对异步数据的解决方案感兴趣 下一步是用从服务器获取的一些数据替换设备。数据是异步的。。所以我仍然需要一个有承诺的解决方案

EDIT5:测试代码:

grandchildren: function(){
  var res = Ember.ArrayProxy.create({content: Ember.A()});

  this.get('parents').forEach(function(parent) {
      var promiseArray = parent.get('children');
      promiseArray.then(function() {
        res.pushObjects(promiseArray.toArray());
      });
    });

  return res;
}.property('parents', 'parents.@each.children')
你可能正在寻找

当你给孙子孙女打电话时,你会得到一个承诺,这个承诺会解决连接的结果


在未来,它看起来将通过类似于rails的方式支持hasMany

首先,你为什么不建立一个模型
person
,然后说一些类似父母的话:DS.hasMany('person')。这将有助于简化模型类型。因此,看起来您可能需要研究如何将树结构展平为
祖父母中的
子函数
的数组。。请参见编辑2此时,您可能需要使用
ArrayProxy
。类似于:
var-granterens=Ember.ArrayProxy.create({content:[]})
然后
pushObject
s转到你的承诺中的数组。@claptimes今天我将用真实数据库替换我的装置。。因此,我的数据可能会再次异步->并且我将不得不更改为您建议的解决方案。。我会告诉你事情的进展