如何过滤Ember.js中的本地hasMany记录集

时间:2015-07-22 12:02:27

标签: javascript ember.js

我在过滤ul个hasMany对象时遇到dom更新问题。这是我正在努力实现的目标:

enter image description here

当用户点击其中一个链接时,它应该过滤掉包含相应元素的div。这是我目前的代码:

路线

import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin,{
  model: function (params) {
    return this.store.find('recipient', params.recipient_id);
  },

  setupController: function (controller, model) {
    this._super(controller, model);
    var categories = model.get('offers').map(function(offer){
      var category = Ember.Object.create();
      category.name = offer.get('company_industry');
      category.count = model.get('offers').filterBy('company_industry', offer.get('company_industry')).get('length');
      return category;
    });

    controller.set('categories', categories);
  }

});

这会将categories设置为Ember对象,因此: {name: 'Home And Beauty', count: 1}

组件:filterable-offers.js

import Ember from 'ember';

export default Ember.Component.extend({

  actions: {
    filter: function(categoryName) {
      return this.get('model').get('offers').filterBy("company_industry", categoryName);
    }
  }

});

过滤-offers.hbs

<ul>
  {{#each categories as |category|}}
      <li>
        <a {{action "filter" category.name}}>{{category.name}} ({{category.count}})</a>
      </li>
  {{/each}}
</ul>

recipient.hbs

  <div class="row">
  <div class="col-sm-4">
    {{filterable-offers categories=categories model=model}}
  </div>
  <div class="col-sm-8">
    {{#each model.offers as |offer|}}
      <div class="offer-card">
        {{offer.text}}
      </div>
    {{/each}}
  </div>

我知道我遗漏了一些简单的东西,比如在这里观察一些东西,但是当我点击链接过滤元素时,dom中没有任何更新。过滤器函数确实返回了我想要的结果集,但主收件人模板中的model.offers调用没有观察到它。

1 个答案:

答案 0 :(得分:2)

您的问题是您从操作处理程序返回过滤后的结果。操作处理程序不使用返回值(大多数情况下)。相反,您需要将过滤后的项目放在模板可以访问它们的位置。由于您的过滤器选择器位于不同的组件中,这就是我要做的(如果您对此任何部分有疑问,请询问):

  1. 在您的组件中,重新发送过滤器操作,使其冒泡到控制器:

    "spanning"
  2. 确保您的控制器可以通过在模板中订阅它来接收操作:

    actions: {
        filter(categoryName) {
            this.sendAction('filterByCategory', categoryName);
        }
    }
    
  3. 在控制器中为{{filterable-offers categories=categories filterByCategory='filterByCategory'}} 操作添加处理程序:

    filterByCategory
  4. 设置一个计算属性,该属性将根据过滤器类别自动过滤您的项目。我们在控制器上有actions: { filterByCategory(categoryName) { // We'll use this in the next step this.set('filterCategory', categoryName); } } 属性,所以让我们使用:

    filterCategory
  5. 最后,不要在模板中使用filteredOffers: Ember.computed('model.offers.@each.company_industry', 'filterCategory', { get() { const offers = this.get('model.offers'); const filterCategory = this.get('filterCategory'); // If there's no category to filter by, return all of the offers if (filterCategory) { return offers.filterBy('company_industry', filterCategory); } else { return offers; } } }) ,而是使用model.offers

    filteredOffers
  6. 这个答案可能比你想要的更深入,但希望它有所帮助。您遇到的主要问题是您需要某种方式告诉控制器使用过滤的一组优惠而不是原始设置。这只是实现这一目标的众多方法之一。