我有一个'has-many'帮助器(感谢In an ember component template how can I use 'if' to check for at least one of an array having a property equal to X?中@GJK的帮助),它允许我在模板中检查一个级别的数组,以便在属性上匹配:
helpers/has-many.js
import Ember from 'ember';
// Param[0]: Array to iterate over
// Param[1]: Comparison operator to use, currently supports '===', '>', '<' and nested 'has-any'
// Param[2]: Value to check for
// (Optional) Param[3]: The property of the arrayObject to check, if this is not supplied the element of the array is checked directly
// Returns: True if array has at least one match to value
export function hasAny(params) {
console.log(params);
var compare = function(a, b, operator) {
console.log(a + ' ' + b + ' ' + operator);
if (operator === '===') {
return a === b;
}
if (operator === '>') {
return a > b;
}
if (operator === '<') {
return a < b;
}
return false;
};
if (params.length < 3) {
return false;
}
if (params[0] === undefined || params[1] === undefined || params[2] === undefined) {
return false;
}
if (params.length === 3) {
return params[0].any((item) => compare(item, params[2], params[1]));
}
if (params[3] === undefined) {
return false;
}
return params[0].any((item) => compare(item.get(params[3]), params[2], params[1]));
}
export default Ember.Helper.helper(hasAny);
我现在想为此添加第二级,以便我可以做相同的
notification.account.contacts.Any(c => c.communications.Any(cm => cm.communicationType.description === 'Email'));
我尝试使用以下内容添加到我的代码中:
助手/具有-many.js
import Ember from 'ember';
// Param[0]: Array to iterate over
// Param[1]: Comparison operator to use, currently supports '===', '>', '<' and nested 'has-any'
// Param[2]: Value to check for
// (Optional) Param[3]: The property of the arrayObject to check, if this is not supplied the element of the array is checked directly
// Returns: True if array has at least one match to value
export function hasAny(params) {
console.log(params);
var compare = function(a, b, operator) {
console.log(a + ' ' + b + ' ' + operator);
if (operator === '===') {
return a === b;
}
if (operator === '>') {
return a > b;
}
if (operator === '<') {
return a < b;
}
if (operator.lastIndexOf('has', 0) === 0) {
var innerParams = operator.split('%');
console.log(a);
return hasAny(a, innerParams[1], innerParams[2], b);
}
return false;
};
if (params.length < 3) {
return false;
}
if (params[0] === undefined || params[1] === undefined || params[2] === undefined) {
return false;
}
if (params.length === 3) {
return params[0].any((item) => compare(item, params[2], params[1]));
}
if (params[3] === undefined) {
return false;
}
return params[0].any((item) => compare(item.get(params[3]), params[2], params[1]));
}
export default Ember.Helper.helper(hasAny);
然后在模板中我有:
{{#if (has-any notification.account.contacts 'has-any%===%Email' 'communicationType.description' 'communications')}}
<p>working!</p>
{{/if}}
我遇到的问题是虽然模板知道一旦notification.account.contacts从API解决后再次触发帮助器,但是一旦每个联系人的通信都从API中断了,它就不知道再次出现 - 我怎么能强制模板/助手获得我的下一级承诺?
编辑1 这些是模型(略微剥离,但有关键字段):
模型/订单notification.js
Export default DS.Model.extend({
orderNotificationType: DS.belongsTo('orderNotificationType', {async: true}),
orderNotificationDetail: DS.attr('string'),
sent: DS.attr('boolean'),
account: DS.belongsTo('account', {async: true}),
});
模型/ account.js
export default DS.Model.extend({
name: DS.attr('string'),
accountType: DS.hasMany('accountType', {async: true}),
contacts: DS.hasMany('contact', {async: true}),
addresses: DS.hasMany('address', {async: true}),
});
模型/ contact.js
export default DS.Model.extend({
title: DS.attr('string'),
firstName: DS.attr('string'),
lastName: DS.attr('string'),
accounts: DS.hasMany('account', {async: true}),
communications: DS.hasMany('communication', {async: true})
});
模型/ communication.js
export default DS.Model.extend({
value: DS.attr('string'),
communicationType: DS.belongsTo('communicationType', {async: true}),
contact: DS.belongsTo('contact', {async: true})
});
模型/通信type.js
export default DS.Model.extend({
description: DS.attr('string'),
communications: DS.hasMany('communication', {async: true})
});
编辑2
我有一些近乎工作的东西:
{{#each notification.account.contacts as |contact index|}}
{{#each contact.communications as |communication id|}}
{{#if (has-any contact.communications '===' 'Email' 'communicationType.description' communication.communicationType.description)}}
<p>Working!</p>
{{/if}}
{{/each}}
{{/each}}
通过进入每个并将第四个参数传递给has-any帮助器(未使用),所有的promise都得到了解决 - 我遇到的问题是<p>Working!</p>
多次出现(因为任何通过多个联系人/通信多次满足。如果#each中有一种方法只在第一次满足if时才显示if块的内容,则此方法可以工作。
答案 0 :(得分:1)
所以我不能按照我想要的方式做到这一点,但GLK让我朝着正确的方向前进。在最低层,我在通信模型中使用了communicationType.description:
communicationTypeDescription: Ember.computed.alias('communicationType.description')
然后我在下一级别的房产中观察到
communicationsAvailable: function() {
var commsAvailable = [];
this.get('communications').forEach(function(comm) {
commsAvailable.push(comm.get('communicationType.description'));
});
return commsAvailable.filter(function(value, index, ca) {
return ca.indexOf(value) === index;
});
}.property('communications.@each.communicationTypeDescription')
然后我在我的帐户模型中观察到下一层的可观察性(你可以重复这一点,无论你需要多深):
communicationsAvailable: function() {
var commsAvailable = [];
this.get('contacts').forEach(function(contact) {
commsAvailable.push.apply(commsAvailable, contact.get('communicationsAvailable'));
});
return commsAvailable.filter(function(value, index, ca) {
return ca.indexOf(value) === index;
});
}.property('contacts.@each.communicationsAvailable')
请注意push.apply
的细微差别。
最后,我在我的模板中以3个参数形式使用了我的has-many函数:
{{#if (has-any notification.account.communicationsAvailable '===' 'Email')}}
<p>Working!</p>
{{/if}}