2015-01-25 3 views
1

Как фильтровать содержимое в контроллере массива с массивом?Фильтр массива с массивом

Я знаю, что могу сделать это для нескольких фильтров:

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», это очень помогло бы мне.

ответ

0

я решил занять некоторое вдохновение 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; 
    } 
1

Я не уверен, если я правильно вас понял, но я дам попробовать:

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).

1

Если фильтры являются более сложными, чем простая проверка для свойств, вы можете создать массив функций, а затем проверить, если каждый 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.

Смежные вопросы