0

我很想知道是否有一种方法可以在不了解要计算的属性值的情况下创建计算属性。例如,如果我有以下模型:

TR.location = DS.Model.extend({
    name: DS.attr('string'),
    city: DS.attr('string'),
    state: DS.attr('string'),
    type: DS.attr('string')
});

带有以下固定装置:

TR.location.FIXTURES = [
    { id: 1, name: 'The Four Seasons', city: 'New York', state: 'NY', type: 'Restaurant' },
    { id: 2, name: 'Le Cirque', city: 'New York', state: 'NY', type: 'Restaurant' },
    { id: 3, name: 'The Russian Tea Room', city: 'New York', state: 'NY', type: 'Restaurant' },
    { id: 4, name: 'The Waldorf Astoria', city: 'New York', state: 'NY', type: 'Hotel' },
    { id: 5, name: 'The Plaza', city: 'New York', state: 'NY', type: 'Hotel' }
];

我想根据“类型”属性显示总数。因此,有了以上信息,我想在我的模板中显示以下内容:

餐厅:3

酒店:2

这里的问题是没有关于“类型”属性的值可能是什么的领域知识,这就是为什么我无法弄清楚如何为上述创建计算属性的原因。有什么解决方法吗?提前致谢。

4

2 回答 2

1

filterProperty 是你的朋友。请参阅http://emberjs.com/api/classes/Ember.Enumerable.html#method_filterProperty

无聊的内联

 var models = TR.location.find();

 var hotelCount = models.filterProperty('type','Hotel').get('length);
 var restaurantCount = models.filterProperty('type', 'Restaurant').get('length');

正如已经指出的那样,您可能不知道类型是什么,在这种特定情况下,为了提高性能,我会进行观察,迭代列表并将它们相加。基本上,只要模型中任何项目的类型更新,您的属性“someCustomCounts”也会更新。

 someCustomCounts: function(){
   var agg= {};
   this.get('model').forEach(function(item){
     var type = item.get('type');
     if(!agg[type]) agg[type] = 0;
     agg[type]++;
   });
   return agg;
 }.observes('model.@each.type'),

在一些数组控制器上,模型设置为位置列表,计算属性

 hotelCount: function(){
    return this.get('model').filterProperty('type','Hotel').get('length);
 }.property('model'),

 restaurantCount: function(){
    return this.get('model').filterProperty('type','Restaurant').get('length);
 }.property('model'),
于 2013-08-27T04:28:39.450 回答
0

根据完成的聚合数量,一个不错的选择可能是使用 Ember.Map,因为它的结构非常适合这些问题。

对于您遇到的具体问题,我们可能会遇到这样的情况:

groupCount: function() {
  var listResult = [];
  // aggregating data
  var mapResult = this.get('content').mapProperty('type').reduce(function(previousValue, item, index, enumerable) {
    var currentItemCount = (previousValue.get(item) || 0);
    previousValue.set(item, currentItemCount + 1);
    return previousValue;
  }, Ember.Map.create());
  // prepare data for displaying in the template
  mapResult.forEach(function(key, value) {
    listResult.push({type: key, count: value});
  });
  return listResult;
}.property('content.@each.type')

计算属性的第一部分负责根据需要聚合信息,第二部分设置数据以在模板中显示。如果数组发生变化,这些值也会重新计算。

这是一个带有此示例的 jsbin:http://jsbin.com/OhenaPe/4/edit?html,js, output

于 2013-08-27T09:02:09.283 回答