带数组的过滤器数组控制器

Filter array controller with array

如何使用数组过滤数组控制器中的内容?

我知道我可以对多个过滤器执行此操作:

App.ItemsController = Ember.ArrayController.extend({

filter: function() {

  var content = this.get("content");

  return content.filter(function(data) {
    return (data.get("foo1")) &&
     (data.get("foo2")) &&
     (data.get("foo3"));
  });
}

});

或只有一个:

return content.filterBy("foo1");

但是如果我想用数组进行过滤,我该怎么做呢?

我想象的是这样的:

var array = ["foo1", "foo2", "foo3"];
return content.filterBy(array);

但这显然行不通

我问是因为我使用了多达 20 个过滤器,如果我可以用数组来完成它会很有帮助。

如果有人 "ember way" 可以做到这一点,那将对我有很大帮助。

我不确定我是否理解正确,但我会试一试:

var filters = ["a", "b", "c"];
var array = [{a: 1, b: 2, c: 3}, {a: 2, b: 3}]
var result = array.filter(function(item) {
  var isPresent = true;
  filters.forEach(function(filter) {
    if (!Ember.isPresent(item[filter])) {
      isPresent = false;
    }
  });
  return isPresent;
});

或者如果您使用下划线或 lodash:

var filters = ["a", "b", "c"];
var array = [{a: 1, b: 2, c: 3}, {a: 2, b: 3}]
var result = array.filter(function(item) {
  return _.all(filters, function(filter) {
    return Ember.isPresent(item[filter]);
  });
});

同样,如果您想将它与 Ember 结构一起使用,您可以将 item[filter] 更改为 item.get(filter)

如果您的过滤器比简单的属性检查更复杂,您可以创建一个函数数组,然后检查每个 item 是否通过:

App.IndexRoute = Ember.Route.extend
  model: ->
    [
      Em.Object.create
        color: 'red'
        isReallyRed: false
      Em.Object.create
        color: 'red'
      Em.Object.create
        color: 'red'
        isReallyRed: true
    ]

App.IndexController = Em.ArrayController.extend
  init: ->
    @_super()
    Em.run.next @, 'filterContent'

  filters: [
    (item) ->
      item.get('color') is 'red'
    , (item) ->
      item.get('isReallyRed')
  ]

  filterContent: ->
    filters = @get 'filters'
    result = @filter (item) ->
      pass = true
      filters.forEach (filter) ->
        if pass
          pass = filter item
      pass
    @set 'content', result

Demo.

我决定从 andrusieczko 和 Daniels 的回答中获得一些灵感,通过对象而不是数组来过滤它。

  App.ItemsController = Ember.ArrayController.extend({

  filterlist: {},

  filters: function() {
    var self = this;
    var content = this;
    var filterlist = this.get("filterlist");

    var allfilters = ["a", "b", "c"]; 

    // set filterlist if any
    allfilters.forEach(function(filter){
      if ( self.get(filter) ) {
        var value = self.get(filter);
        filterlist[filter] = value;
      }
    });

    // if equal or higher return y. else n.
    function equal(item, key) {
      var data = item.get(key);
      var thefilter = self.get(key);

      if ( data >= thefilter ) {
        return "y";
      } else {
        return "n";
      }
    };

    filter = content.filter(function(item) {
      var pass = "";

      if ( jQuery.isEmptyObject(filterlist) ) {
        return true;
      } else {

        $.each(filterlist, function(key, value){
            var pass2 = pass;
            return pass = pass2 + equal(item, key);

        });
        if ( pass.indexOf("n") === -1 ) {
          return pass;
        }
      }
    });

    return filter;
  }