简体   繁体   English

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

[英]How to filter a local hasMany record set in Ember.js

I am having issues making the dom update when filtering a ul of hasMany objects. 我在过滤ul hasMany对象的ul时会导致dom更新的问题。 Here is what I'm trying to accomplish: 这是我要完成的工作:

在此处输入图片说明

When a user clicks on one of the links it should filter down a div containing the respective elements. 当用户单击其中一个链接时,它应过滤包含相应元素的div。 Here is my current code: 这是我当前的代码:


Route 路线

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

});

This sets categories to an Ember object liks so: {name: 'Home And Beauty', count: 1} 这会将categories设置为一个Ember对象,例如: {name: 'Home And Beauty', count: 1}

Component: filterable-offers.js 组件: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);
    }
  }

});

filterable-offers.hbs 过滤,offers.hbs

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

recipient.hbs 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>

I know I'm missing some simple like observing something here, but when I click the link to filter down the elements nothing is updated in the dom. 我知道我缺少一些简单的功能,例如在此处进行观察,但是当我单击链接以过滤掉元素时,dom中没有任何更新。 The filter function does return the result set I want but it isn't being observed by the model.offers call in the main recipient template. 过滤器功能确实返回了我想要的结果集,但是主接收者模板中的model.offers调用未观察到结果集。

Your problem is that you're returning your filtered result from your action handler. 您的问题是您要从操作处理程序返回过滤的结果。 The action handler doesn't use a return value (for the most part). 动作处理程序不使用返回值(大部分情况下)。 Instead, you need to place your filtered items somewhere where your template can access them. 相反,您需要将过滤后的项目放置在模板可以访问它们的地方。 Since your filter selector is in a different component, this is what I would do (if you have questions about any part of this, just ask): 由于您的过滤器选择器位于不同的组件中,所以这就是我要做的(如果您对此部分有任何疑问,请询问):

  1. In your component, re-send the filter action so it bubbles to the controller: 在您的组件中,重新发送filter操作,使它冒泡到控制器:

     actions: { filter(categoryName) { this.sendAction('filterByCategory', categoryName); } } 
  2. Make sure your controller can receive the action by subscribing to it in the template: 通过在模板中进行订阅来确保您的控制器可以收到该动作:

     {{filterable-offers categories=categories filterByCategory='filterByCategory'}} 
  3. Add a handler for the filterByCategory action in your controller: 在控制器中为filterByCategory操作添加处理程序:

     actions: { filterByCategory(categoryName) { // We'll use this in the next step this.set('filterCategory', categoryName); } } 
  4. Set up a computed property that will automatically filter your items based on the filter category. 设置一个计算属性,该属性将根据过滤器类别自动过滤您的项目。 We have our filterCategory property on the controller, so let's use that: 我们在控制器上具有filterCategory属性,因此我们可以使用它:

     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; } } }) 
  5. Finally, instead of using model.offers in your template, use filteredOffers 最后,不要在模板中使用model.offers ,而要使用filteredOffers

      {{#each filteredOffers as |offer|}} ... {{/each}} 

That answer might be a tad more in-depth than you want, but hopefully it helps. 这个答案可能比您想要的更深入,但是希望它会有所帮助。 The major sticking point you were having is that you needed some way to tell your controller to use a filtered set of offers instead of the original set. 您遇到的主要问题是,您需要一种方法来告诉您的控制器使用一组经过筛选的商品而不是原始商品。 This is just one of many ways to accomplish that. 这只是完成此操作的许多方法之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM