Ember.js计算属性筛选器有多个数组

Ember.js计算属性筛选器有多个数组,ember.js,ember-data,Ember.js,Ember Data,我试图过滤余烬数据“hasMany”字段的内容。我的模型有一些子问题,我想将它们过滤到控制器上的属性“childOptions”中,并使用 {{#each childOptions}}stuff{{/each}} 当我将其放在控制器上时,它会工作,并且每个都会在适当的值上迭代: childOptions: Ember.computed.filterBy('model.subquestions', 'surveyQuestionType.name', 'childOption'), 然而,当我

我试图过滤余烬数据“hasMany”字段的内容。我的模型有一些子问题,我想将它们过滤到控制器上的属性“childOptions”中,并使用

{{#each childOptions}}stuff{{/each}}
当我将其放在控制器上时,它会工作,并且每个都会在适当的值上迭代:

childOptions: Ember.computed.filterBy('model.subquestions', 'surveyQuestionType.name', 'childOption'),
然而,当我这样做时,什么都没有显示

childOptions: Ember.computed.filter('model.subquestions', function(subquestion) {
    return subquestion.get('surveyQuestionType.name') === 'childOption';
}),
“surveyQuestionType”是存在于“子问题”模型上的DS.belongsTo,它具有“name”属性

我想了解为什么“filterBy”方法有效,而“filter”方法无效(这样我将来可以在更复杂的查询中使用“filter”)。我认为这与承诺以及我在filter函数中使用的
子问题.get('property')
语法有关

编辑:

这就是模型:

App.SurveyQuestion = DS.Model.extend(Ember.Validations.Mixin, {
    surveyQuestionType: DS.belongsTo('surveyQuestionType', { async: true }),
    display: DS.belongsTo('surveyQuestionDisplay', { async: true, inverse: 'surveyQuestion' }),
    sortOrder: DS.attr('number'),
    parent: DS.belongsTo('surveyQuestion', { async: true, inverse: 'subquestions' }),
    parentDependencyCriteria: DS.attr('string'),
    required: DS.attr('boolean'),
    surveySections: DS.hasMany('surveySectionQuestion', { async: true, inverse: 'surveyQuestion' }),
    subquestions: DS.hasMany('surveyQuestion', { async: true, inverse: 'parent' })
});

我在自己的工作中发现这类问题的时间比我愿意承认的要多,但幸运的是,解决方法很简单。在您的
DS.Model
定义中,
surveyQuestionType
a
是否属于与
{async:true}
的关系?如果是这样,那就是你的问题

无论何时在
DS.Model
中将关系设置为
{async:true}
,您都可以将其视为实际设置了一个承诺,即您最终将获得该属性。这是有道理的,而且是直观的,但是没有很好的文档记录

承诺对于初学者来说尤其棘手,因为您的手柄模板将透明地处理
{{surveyQuestionType.name}}
是否
surveyQuestionType
是具体值还是承诺。这让初学者感到困惑,因为你无法在第一眼就看出车把是否提供了一个具体的价值或承诺

当您处理承诺时,可以直接访问该承诺在其
内容
属性中解析的内容。事实上,您甚至可以设置
content
属性。但是要小心,因为直接读/写
内容
属性对promise可能具有的任何挂起操作没有影响。因此,如果在写入其
内容
值时承诺仍处于挂起状态,那么一旦它解析,您的写入将被覆盖

当我添加新实体并需要填充承诺关系时,我直接写入
内容
属性。这是有道理的,但如果我正在读取一个值,我需要找到一些方法来保证我自己在读取
内容
属性时承诺已经解决了……或者,我可以让Handlebar直接处理这个问题,因为我知道,对于纯显示逻辑,我不关心150毫秒的延迟

无论如何,如果以上所有内容都适用于您的问题,那么您可以通过以下方式编辑代码以使其正常工作:

childOptions: Ember.computed.filter('model.subquestions', function(subquestion) {
    return subquestion.get('surveyQuestionType.content.name') === 'childOption';
})
更新#1:我认为我只是违反了我自己的建议,没有仔细地访问
内容。有关调试的信息,请参见我的评论,您也可以尝试以下方法:

childOptions: Ember.computed.filter('model.subquestions', function(subquestion) {
    return subquestion.get('surveyQuestionType').then( function( model ) {
       return model.get('name') === 'childOption';
    });
})
更新#2:请参见下面我的评论,特别是。事实证明,这是一个更棘手的问题,我欢迎其他人的意见,以澄清这里的最佳方法


我在自己的代码中解决了这个问题,方法是在上游处理承诺,这样我就可以直接访问
内容
属性,或者根本不在我的过滤器中处理承诺。

从ember data 1.0.0-beta.11开始,承诺似乎工作得更顺利,我在这方面取得了成功(实际上,我对我的原始问题采用了不同的方法,但在类似情况下使用了此代码):


.property('subquestions.@each.surveyQuestion')
导致在
surveyQuestion
承诺解决时更新属性。如果输入一些输出,您将看到最初调用属性,并且
subquestions
将为null。

subquestion.get('surveyQuestionType.name'))
返回
未定义的
,我很确定这是问题所在,但我不知道如何解决它!如果我做一个简单的
{{{{每个子问题}}{{surveyQuestionType.name}{{/每个}}
在我的模板中,我可以很好地看到属性。感谢您的解释,您对
async:true
的回答是正确的。但是,您的回答不太有效。可能是subquestions属性也是一个promise数组。
.property()
在使用
Ember.computed.filter
时不需要添加内容?理想情况下,我希望在承诺得到解决后进行过滤,对吗?Re:
.property()
,您是正确的,谢谢您指出。我将更新我的答案。我将很快回应其他问题。Re:这不起作用,我有两个想法。(1)确切地知道你正在处理的每个实体是什么是很有帮助的。因此,尝试
console.log(this.get('model.subquestions').toString())
这将告诉你这是一个承诺还是具体的价值。你还应该看看优秀的我可能在原始答案中犯了错误,因为我访问了承诺中的内容,但该代码不会等到承诺解析后才读取值。请查看更新的答案。对于原始响应中的错误,我深表歉意。返回
中的值后,
将不起任何作用。这将最终在承诺的价值(这将永远是真的)。好的,在过滤器中使用异步比我最初意识到的要复杂得多。请参阅。我个人已经通过进一步向上游解决我的承诺来解决了这个问题。我的回答解决了部分问题,但没有给出完整的解决方案。“如果(子问题)”被忽略,并添加一个.property(“childOptions”),在您使用函数的每个位置。没有测试它,但应该可以工作。我使用了.any而不是filter,它可以工作。
childOptions: function() {
    var subquestions = this.get('subquestions');
    if (subquestions) {
        return subquestions.filter(function(subquestion) {    
            var surveyQuestion = subquestion.get('surveyQuestion');
            return (surveyQuestion && surveyQuestion.get('name') === 'childOptions');
        });
    }
}.property('subquestions.@each.surveyQuestion')