Ember.js计算属性筛选器有多个数组
我试图过滤余烬数据“hasMany”字段的内容。我的模型有一些子问题,我想将它们过滤到控制器上的属性“childOptions”中,并使用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'), 然而,当我
{{#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')