[英]How to add Css Class to item inside Ember's {{#each}} loop, according to index? - Ember.js
我有一個帶有側菜單的Ember應用程序。 html中的菜單項基於Ember的{{each}}循環。 當用戶選擇菜單項時,我要添加此項目活動類。
如何根據控制器的條件將css類添加到Ember的{{each}}中的單個項目中。
Html / Hbs:
<ul>
{{#each menuItem in sideMenuItems}}
<li {{bind-attr class="isActive: active-class"}} {{ action 'selectMenuItem' _view.contentIndex }}>
{{ menuItem.text }}
</li>
{{/each}}
</ul>
控制器:
Ember.ObjectController.extend({
selectedMenuIndex: 0,
isActive: function() {
return (this.get('selectedMenuIndex') == ? ? ? );
}.property('???'),
actions: {
selectMenuItem: function(itemIndex) {
this.set('selectedMenuIndex', itemIndex);
}
}
})
當用戶選擇菜單項時,我要添加此項目活動類。
最簡單的方法是向項目本身添加一個標志isActive
,並將其用作css類的條件。 您可以在selectMenuItem
操作selectMenuItem
單擊項的標志設置為true
。 如果您的邏輯一次只允許一個項目處於活動狀態,則還必須將任何當前活動項目的isActive
標志重置為false
。
{{#each menuItem in sideMenuItems}}
<li {{bind-attr class="menuItem.isActive:active-class"}} {{action 'selectMenuItem' _view.contentIndex}}>
{{menuItem.text}}
</li>
{{/each}}
控制器:
Ember.ObjectController.extend({
sideMenuItems: // ... your array of items, each containing an isActive flag
actions: {
selectMenuItem: function(itemIndex) {
var items = this.get('sideMenuItems');
items.forEach(function(item, idx) { // go through the items,
if(idx === itemIndex) { // find the clicked item and set it as active
Ember.set(item, 'isActive', true);
} else { // reset all other items
Ember.set(item, 'isActive', false);
}
});
}
}
})
一種更有效的方法是將當前活動的項目存儲為單獨的變量,這將消除對sideMenuItems
數組進行兩次迭代的需要:
控制器:
Ember.ObjectController.extend({
sideMenuItems: // ... your array of items, each containing an isActive flag
activeMenuItem: null,
actions: {
selectMenuItem: function(itemIndex) {
var items = this.get('sideMenuItems');
var currActive = this.get('activeMenuItem');
var nextActive = items.objectAt(itemIndex);
// if there is a currently active item, deactivate it
if(currActive) {
Ember.set(currActive, 'isActive', false);
}
// if the user clicked on the currently active item, we just reset the selected item
// otherwise we update the isActive flag for the clicked item
if(currActive === nextActive) {
nextActive = null;
} else {
Ember.set(nextActive, 'isActive', true);
}
// set the clicked item as the currently active menu item
this.set('activeMenuItem', nextActive);
}
})
另一種方法是創建一個自定義組件menu-item
,該menu-item
根據活動索引呈現帶/不帶類的li
項目。
Ember.Component.extend({
// passed in
activeIndex: -1,
index: -1,
selectMenuItemAction: '',
// local
tagName: 'li',
classNameBindings: ['activeClass'],
activeClass: function() {
var idx = this.get('index');
var activeIdx = this.get('activeIndex');
// if the current item is the active index, return the active class
if(idx === activeIdx) {
return 'active-class';
}
// otherwise return no class
return '';
}.property('activeIndex')
actions: {
selectMenuItem: function() {
this.sendAction('selectMenuItemAction', this.get('index'));
}
}
})
然后像這樣使用它:
{{#each menuItem in sideMenuItems}}
{{#menu-item index=_view.contentIndex activeIndex=selectedMenuIndex selectMenuItemAction="selectMenuItem"}}
{{menuItem.text}}
{{/menu-item}}
{{/each}}
控制器:
Ember.ObjectController.extend({
selectedMenuIndex: 0,
actions: {
selectMenuItem: function(itemIndex) {
this.set('selectedMenuIndex', itemIndex);
}
}
})
由於使用_view.contentIndex
有點_view.contentIndex
,因此您可以只傳遞實際的菜單項,然后比較對象引用而不是索引來確定活動項:
菜單項組成:
Ember.Component.extend({
// passed in
activeItem: null,
item: null,
selectMenuItemAction: '',
// local
tagName: 'li',
classNameBindings: ['activeClass'],
activeClass: function() {
var item = this.get('item');
var activeItem = this.get('activeItem');
// if the current item is the active item, return the active class
if(item === activeItem) {
return 'active-class';
}
// otherwise return no class
return '';
}.property('activeItem')
actions: {
selectMenuItem: function() {
this.sendAction('selectMenuItemAction', this.get('item'));
}
}
})
然后像這樣使用它:
{{#each menuItem in sideMenuItems}}
{{#menu-item item=menuItem activeItem=selectedMenuItem selectMenuItemAction="selectMenuItem"}}
{{menuItem.text}}
{{/menu-item}}
{{/each}}
控制器:
Ember.ObjectController.extend({
selectedMenuItem: null,
actions: {
selectMenuItem: function(item) {
this.set('selectedMenuItem', item);
}
}
})
Ember> 1.13支持內聯幫助器,因此您可以按照自己的意願實現此目的。 Ember CLI 1.13也隨babel一起提供,因此我們也可以使用ES6,從而可以進一步簡化:
控制器:
Ember.Controller.extend({
selectedMenuIndex: 0,
menuItems: // ...
actions: {
selectMenuItem(itemIndex) {
this.set('selectedMenuIndex', itemIndex);
}
}
});
模板:
{{#each menuItems as |item index|}}
<li class="{{active-class index selectedMenuIndex}}" {{action "selectMenuItem" index}}>
{{item.text}}
</li>
{{/each}}
幫手:
activeClass(params) {
const [ index, active ] = params; // use ES6 destructuring
return (index === active) ? 'active-class': '';
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.