EmberJS如何构建动态过滤

时间:2016-09-16 18:51:29

标签: javascript sorting ember.js filtering

我有一个可以分类,过滤和查询的项目列表。

对它们进行排序非常简单:

var ToDoList = Ember.Object.extend({
  // using standard ascending sort
  todosSorting: ['name:desc'],
  sortedTodos: Ember.computed.sort('todos', 'todosSorting')
});

然后,您可以轻松地将todosSorting的值更改为例如['name:asc']或每个待办事项的名称。 EmberJS魔术将对一切进行排序。您甚至可以将todosSorting更改为todos的另一个属性,它只是有效。

过滤效果似乎不那么强大。您可以提供功能或键加值。它并不像排序那么强大。您可以更改每个待办事项的过滤属性,并过滤列表。但是如何更改过滤器的值或键?

有没有办法达到与.sort()相同的灵活性?

e.g:

var ToDoList = Ember.Object.extend({
  todosFilteringKey: 'priority',
  todosFilteringValue: 1,
  filteredTodos: Ember.computed.filter('todos', 'todosFilteringKey', 'todosFilteringValue')
});

目前我是这样实现的:

var ToDoList = Ember.Object.extend({
  currentFilter: 'all',
  filterBy: Ember.computed('currentFilter', function() {
    return this.filters[this.get('currentFilter')];
  }),

  filters: {
    all: function(item) {
      return true;
    },

    priority1: function(item) {
      return item.get('priority') === 1;
    },

    priority2: function(item) {
      return item.get('priority') === 2;
    },
  }

  filteredTodos: Ember.computed('todos', 'filterBy', 'todos.@each.priority', function () {
    return this.filter();
  }),

  filter: function() {
    return this.get('todos').filter(function(todo) {
      return this.get('filterBy')(todo);
    }.bind(this));
  },
});

如果您有多种过滤可能性,则无法很好地扩展

1 个答案:

答案 0 :(得分:0)

您可以通过多种不同方式撰写此文章。与sort不同,filterfilterBy API不提供按给定键和值动态过滤的方法。但您可以使用以下代码为自己实现该API:

var filterByKeyAndValue = function filterByKeyAndValue(items, key, value) {
  return items.filter(function (item) {
    return Ember.get(item, key) === value;
  });
};

var ToDoList = Ember.Object.extend({

  currentPriority: null,

  filteredTodos: Ember.computed('todos', 'todos.@each.priority', 'currentPriority', function() {
    if (!this.get('currentPriority')) {
      // slice ensures we consistently return a new Array.
      return this.get('todos').slice();
    }

    return filterByKeyAndValue(this.get('todos'), 'priority', this.get('currentPriority'));
  }),

});

这有用吗?

我已经在这里硬编码了密钥('priority'),但当然,你也可以将其分解为Ember.Object。