如何动态地将类应用于ember-cli中的对象?

时间:2015-05-03 05:19:35

标签: ember.js ember-cli

我正在创建一个应用程序,其中包含项目列表和顶部的一系列过滤器按钮。当用户应用不同的过滤器时,我希望按钮使用CSS类来更改样式,以将其显示为启用/禁用。

我希望能够编写类似下面代码的内容,但它不起作用。

{{#each category in category_options}}
  <button {{action "filterCategory" category}} {{bind-attr class=":btn-small isFiltered(category):btn-active:btn-inactive"}}>{{category}}</button>
{{/each}}

在此示例中,isFiltered是控制器上的计算属性,它查看查询参数以确定指定的类别是否已应用为过滤器。

从我所做的阅读中,听起来你无法将参数传递给计算属性。我遇到过提及助手,绑定帮助器和组件的答案,但我无法理清我需要哪一个,或者在这种情况下如何应用它。

编辑: 为了澄清这个例子,假设我有一系列过滤各种标签的按钮:

Filter for: <Cats> <Dogs> <Rabbits> ... # imagine an arbitrary number of these. dozens, maybe

当用户点击Cats时,它会触发filterCategory,它将model.category查询参数设置为['Cats']。如果他然后单击Dogs,则model.category变为['Cats','Dogs']

在后一种情况下,我希望Cats and Dogs按钮让btn-active这个类。

我想像这样定义isFiltered:

isFiltered: function(buttonname) {
  if (this.get('model.categories').containsObject(buttonname)) { # pseudocode
    return true;
  }
  else { return false; }
}

将按钮名传递给函数可以轻松地对每个按钮进行比较,并确定它是否在过滤器中。

如果这种整体方法是错误的做事方式,那么正确的做法是什么?

3 个答案:

答案 0 :(得分:1)

1)作为组件,您可以执行以下操作:

模板中的

{{#each category in category_options}}
  {{category-button category=category selectedCategoies=selectedCategories action="filterCategory"}}
{{/each}}

组件模板

{{category}}

成分<​​/ P>

export default Ember.Component.extend({

  tagName: 'button',
  classNames: 'btn-small',
  classNameBindings: 'isFiltered:btn-active:btn-inactive',

  isFiltered: Ember.computed('category', 'selectedCategories', function(){
    return this.get('selectedCategories').contains(this.get('category'));
  }),
  click: function(){
    this.sendAction('action', this.get('category'));
  }
})

2)或者你可以将你的类别作为对象的数组,如此

[
  {name: 'category1', isActive: false},
  {name: 'category2', isActive: true},
  ...
]

然后根据需要更改isActive标记。

在控制器中:

categoryObjects: Ember.computed('category_options', function(){
  return this.get('category_options').map(function(category){
    Ember.Object.create({name: category, isActive: false});
  })
}),
actions: {
  filterCategory: function(category){
    category.toggleProperty('isActive');
    return
  }
}

在模板中:

{{#each category in categoryObjects}}
  <button {{action "filterCategory" category}} {{bind-attr class=":btn-small category.isActive:btn-active:btn-inactive"}}>{{category.name}}</button>
{{/each}}

答案 1 :(得分:0)

我不确定代码的其余部分是什么样的,但一般情况下,您会在路由中使用model挂钩来获取查询参数,如果需要,可以处理它,并返回您的模型,让我们说你会返回model.category,然后在你的控制器中你会有这样的东西:

isFiltered: function() {
   var category = this.get('model.category');
   // do whatever you want here with category to return true or false
}.property('model.category')

然后在.hbs你可以写下这个:

{{#each category in category_options}}
  <button {{action "filterCategory" category}} {{bind-attr class=":btn-small isFiltered:btn-active:btn-inactive"}}>{{category}}</button>
{{/each}}

答案 2 :(得分:0)

如果你是通过你的方法来做到这一点,你可以通过制作一个计算属性宏,然后循环使用category_options并创建计算属性asCategory(isRed,isBlue等...)来实现它。

但这不是正确的方法,你需要制作那些接受category_options和model.category的按钮组件,并在内部决定它是否应该是活动的。