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

How to dynamically apply classes to objects in ember-cli?

我正在创建一个应用程序,它在顶部有一个项目列表和一系列过滤器按钮。当用户应用不同的过滤器时,我希望按钮使用 CSS classes 更改样式以将它们显示为 enabled/disabled.

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

{{#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

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

在后一种情况下,我希望猫狗按钮具有 class btn-active。

我想这样定义 isFiltered:

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

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

如果这种总体方法是错误的处理方法,那么正确的方法是什么?

我不确定您的其余代码是什么样子,但通常您会在路由中使用 model 挂钩来获取查询参数,并在需要时进行处理,然后 return对于你的模型,假设你会 return 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}}

如果您要通过您的方法执行此操作,则可以通过制作计算 属性 宏然后遍历 category_options 并将计算属性创建为 isCategory ( isRed, isBlue等..)

但这不是正确的方法,您需要制作那些按钮组件,它们将接受 category_options 和 model.category 并在内部决定它是否应该处于活动状态或没有。

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

在模板中

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

组件模板

{{category}}

组件

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}}