2013-02-11 35 views
1

我有一个对象列表,通过Ajax从API中获取。它类似于这样:如何使用Ember.js显示(在视图中)列表子集?

App.Card = Ember.Object.extend({ 
    name: "", 
    color: "" 
}); 

App.cardsController = Ember.ArrayController.create({ 
    content: [], 

    createCard: function(data) { 
    this.pushObject(App.Card.create(data)); 
    }, 

    loadCards: function() { 
    // Fetch API and use createCard 
    } 
}); 

当我使用{{#each App.cardsController}},我列出所有的卡我的控制器内。

但我想按颜色过滤它们。我如何过滤列表(在Controller内容中)并显示它们?

我尝试这样的做法:

添加代码里App.cardsController

filterCardsByColor: function() { 
    array = this.get('content').filter(function(item, index) { 
     return item.get('color') == 'red'; 
    }); 
    return array; 
    }.property('[email protected]') 

并补充{{#each App.cardsController.filterCardsByColor}}我的看法。

但我收到以下错误,在我的Chrome控制台:

Uncaught TypeError: Object [object Object] has no method 'addArrayObserver' ember.min.js:18 

我做错了吗?或者我该怎么做?我应该将该逻辑移至一个视图吗?怎么样?我甚至尝试在Ember.Array.create(array)内包装array,但它没有解决我的问题。

奖励:是否可以发送参数到filterCardsByColor,所以我可以要求'red'卡或'yellow'卡等?

+0

注:我试图使用从http“myFilteredArray'://计算器。com/questions/11502300/how-to-get-index-item-of-array-in-emberjs-view - 我猜我没有正确使用它。 – jmonteiro 2013-02-11 02:31:55

+0

您正在使用哪个版本的Ember.js?定义计算的属性不再是Ember.Object.create – Luan 2013-02-11 03:57:52

+0

@Luan:我正在使用1.0.0-pre4。 – jmonteiro 2013-02-13 12:12:21

回答

2

做到这一点的最好办法是存储阵列,将持有的颜色过滤掉(或过滤器,如果你愿意的话),每一次都有所计算的属性更新其length通过指定的变化.property('colours.length');

filteredContent: function() { 
    // Triggered every time a colour is added/removed. 
    var colours = this.get('colours'); 
    return this.get('content').filter(function(model) { 
     // Determine whether the current model's colour is in the array of those filtered. 
     return Boolean(jQuery.inArray(model.get('colour'), colours) == -1); 
    }); 
}.property('colours.length') 

然后,我们只需要为我们的看法能在色彩传递给添加到阵列的方式。我们可以用一个不同的函数applyFilters来完成这个工作,它将接受一个参数 - 我们希望排除的颜色。您可以像{{action}}那样传递此颜色:<a {{action "applyFilter" "red"}}>

applyFilter: function(colour) { 
    var colours = this.get('colours'); 
    if (!colour) { 
     // Clear all of the colours if we're clearing the filters. 
     colours.clear(); 
     return; 
    } 

    // Otherwise we can push the new colour into the array, which will trigger 
    // an update of the filteredContent computed property. 
    colours.pushObject(colour); 
} 

完全符合工作的jsfiddle你周围的混乱:http://jsfiddle.net/9XmqL/

+0

非常感谢你!如果可以的话,我会为您创建jsfiddle代码片段提供额外的积分:-) – jmonteiro 2013-02-16 20:14:47

+0

对不起,评论中的格式不正确。请参阅下面的答案。 – Fordi 2013-09-03 14:56:12

1

不幸的是,我不认为WildHoney的是最好的答案。

添加以下到他们的CSS:

@-webkit-keyframes onUpdate { 
    from { background: yellow; } 
} 
@keyframes onUpdate { 
    from { background: yellow; } 
} 
* { 
    -webkit-animation: onUpdate 1s; 
    animation: onUpdate 1s; 
} 

我可以看到,当内容被更新,整个列表被重绘。对于很长的名单,这可能是一个严重的表现。

为了避免这种情况,您应该只生成一次提供filteredContent的数组 - 当指向内容的指针发生变化时 - 根据对子集的更改以目标方式更新它。

http://jsfiddle.net/wRzRn/2/

+0

这一切都取决于用例。如果您正在生成任何长列表,则需要考虑所有问题。在开发过程中,您应该从最基本的实现开始,然后根据需求进行调整 - 除非开始时的要求是处理大型数据集。 – Wildhoney 2013-09-03 15:36:30

相关问题