带数组的过滤器数组控制器
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
我决定从 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;
}
如何使用数组过滤数组控制器中的内容?
我知道我可以对多个过滤器执行此操作:
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
我决定从 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;
}