Ember.js计算属性过滤器hasMany数组

lee*_*489 3 ember.js ember-data

我试图过滤ember-data'hasMany'字段的内容.我的模型有一些子参数,我想在我的控制器上过滤到属性'childOptions'并在模板中显示

{{#each childOptions}}stuff{{/each}}
Run Code Online (Sandbox Code Playgroud)

当我把它放在我的控制器上时,它工作,每个迭代适当的值:

childOptions: Ember.computed.filterBy('model.subquestions', 'surveyQuestionType.name', 'childOption'),
Run Code Online (Sandbox Code Playgroud)

但是,当我这样做时,没有显示任何内容.

childOptions: Ember.computed.filter('model.subquestions', function(subquestion) {
    return subquestion.get('surveyQuestionType.name') === 'childOption';
}),
Run Code Online (Sandbox Code Playgroud)

'surveyQuestionType'是DS.belongsTo,它存在于'subquestions'模型中,并且具有'name'属性.

我想理解为什么'filterBy'方法有效,而'filter'方法却没有(因此我将来可以使用'filter'来处理更复杂的查询).我认为这与promises和subquestion.get('property')我在filter函数中使用的语法有关.

编辑:

这是模型:

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' })
});
Run Code Online (Sandbox Code Playgroud)

Jos*_*ick 5

我花了更多时间用我自己的工作来发现这类问题而不是我承认,但幸运的是解决方案很简单.在你的DS.Model定义中,是surveyQuestionType与...的belongsTo关系{async: true}?如果是这样,那就是你的问题.

无论何时在DS.Modelas中设置关系{async: true},您都可以将其视为实际设定的承诺,即您最终将获得该属性.这很有意义并且变得直观,但是没有记录得很好!

承诺是对初学者尤其棘手,因为你的车把模板将透明地处理{{surveyQuestionType.name}}是否surveyQuestionType是一个具体的数值或承诺.这让初学者感到困惑,因为如果Handlebars呈现具体价值或承诺,你不能乍一看.

当您处理承诺时,您可以直接访问该承诺在其content财产中解析的内容.实际上,您甚至可以设置该content属性.但请注意这一点,因为直接读取/写入content属性对承诺可能具有的任何挂起操作没有影响.因此,如果承诺在写入其content值时仍处于未决状态,则一旦结算,您的写入将被覆盖.

content当我添加一个新实体并需要填充一个promise关系时,我直接写入该属性.这在那里是有意义的,但如果我正在阅读一个价值,我需要找到一些方法来保证我在阅读content房产时承诺已经解决了......或者,我可以让Handlebars直接处理这个问题,知道对于纯显示逻辑,我不关心150毫秒的延迟.

无论如何,如果以上所有内容都适用于您的问题,请按照以下步骤编辑代码以使其正常工作:

childOptions: Ember.computed.filter('model.subquestions', function(subquestion) {
    return subquestion.get('surveyQuestionType.content.name') === 'childOption';
})
Run Code Online (Sandbox Code Playgroud)

更新#1:我相信我只是违反了我自己的建议而没有content深思熟虑.有关调试的信息,请参阅我的注释,您也可以尝试这样做:

childOptions: Ember.computed.filter('model.subquestions', function(subquestion) {
    return subquestion.get('surveyQuestionType').then( function( model ) {
       return model.get('name') === 'childOption';
    });
})
Run Code Online (Sandbox Code Playgroud)

更新#2:请参阅下面的评论,特别是https://github.com/emberjs/data/issues/1865.事实证明这是一个棘手的问题,我欢迎其他人的意见,以澄清这里的最佳方法.

我通过处理上游的promises在我自己的代码中解决了这个问题,这样我就可以直接访问该content属性,或者根本不在我的过滤器中处理promises.