Javascript knockout.js中的多个过滤器

Javascript knockout.js中的多个过滤器,javascript,knockout.js,filtering,knockout-2.0,Javascript,Knockout.js,Filtering,Knockout 2.0,假设我有电影阵列,如果我想按类型过滤,我可以这样做 filtered = ko.computed(function() { var self = this; if ( ! self.genresFilter() || self.genresFilter() === 'all') { return this.sourceItems(); } else { return ko.utils.arrayFi

假设我有电影阵列,如果我想按类型过滤,我可以这样做

filtered = ko.computed(function() {
        var self = this;

        if ( ! self.genresFilter() || self.genresFilter() === 'all') {
            return this.sourceItems();
        } else {
            return ko.utils.arrayFilter(self.sourceItems(), function(item) {
                return app.utils.inArray(item.genre, self.genresFilter());     
            });
        }
    }, app.viewModels.games);

但我现在陷入困境的是,如果我有类型、语言和长度的html下拉列表,我如何通过所有或部分过滤器有效地过滤电影,因此,我可以观看俄罗斯动作片或90分钟长的动作片等?

过滤结果是一个值的组合,可以通过迭代所有可能的过滤器,应用用户选择的过滤器,并从结果中删除不适合过滤器的项。应用过滤器的顺序并不重要。这些项必须符合所有条件才能成为有效结果,因此,一旦不符合条件,您可以将其丢弃

这里有一些伪代码

# item1:
# color: red
# price: 5
# language: EN

# item2:
# color: red
# price: 10
# language: RU

# item3:
# color: green
# price: 7
# language: DE


@items = ( item1, item2, item3 );
foreach filter in @selectedFilters {
  foreach item in @items {
    delete item from @items if filter.value != item.<filter.type>
    # or <, >, whatever
  }
}

return @items
#第1项:
#颜色:红色
#价格:5元
#语言:EN
#项目2:
#颜色:红色
#价格:10
#语言:RU
#项目3:
#颜色:绿色
#价格:7
#语文:DE
@项目=(项目1、项目2、项目3);
@selectedFilters中的foreach过滤器{
@items中的每个项目{
如果filter.value!=项目,则从@items中删除项目。
#或者,不管怎样
}
}
返回@items

您需要根据提供的每个筛选器逐步构建筛选列表。至于过滤器本身,它们要么各自由一个可观察对象表示,要么全部在一个可观察对象内表示。这一点很重要,因为当您更改过滤器时,它将触发计算机更新

例如:

var filteredList = ko.computed({
    var currentList = this.sourceItems();
    var currentFilters = this.genresFilters();

    ko.utils.arrayForEach(currentFilters, function () {
        currentList = ko.utils.arrayFilter(currentList, function(filter) {
            return app.utils.inArray(filter, currentFilters);     
        });
    });

    return currentList;
});

此代码将循环通过每个筛选器,获取最新的筛选列表,并仅保留满足所有条件的项。

我知道这是一个旧主题,但最近我遇到了相同的问题,这是我为您的电影模型修改的解决方案。您也可以在此处查看:

var MoviesModel=函数(数据){
var self=这个;
self.Genres=ko.observearray(data.Genres);
自我。体裁。取消移位(“全部”);
self.filterGenre=ko.可观察(“全部”);
self.Languages=ko.observearray(data.Languages);
self.Languages.unshift(“全部”);
self.filterLanguage=ko.可观察(“全部”);
self.length=ko.observearray(数据长度);
自身长度不移位(“全部”);
self.filterLength=ko.可观察(“全部”);
self.movies=ko.observearray(data.movies);
self.filteredMovies=ko.computed(函数(){
var filteredArray=ko.utils.arrayFilter(self.movies(),函数(项){
返回(
(item.genre==self.filterGenre()| | self.filterGenre()=“全部”)&&
(item.language==self.filterLanguage()| | self.filterLanguage()==“全部”)&&
(item.length==self.filterLength()| | self.filterLength()=“全部”)
);
});
返回过滤器阵列;
});
};
风险值数据={
类型:[“戏剧”、“恐怖”、“科幻”],
语言:[“英语”、“俄语”],
长度:[“100”、“120”、“140”、“160”],
电影:[
{名称:“教父”,体裁:“戏剧”,语言:“英语”,长度:“160”},
{名称:“光辉”,体裁:“恐怖”,语言:“英语”,长度:“140”},
{名称:“跟踪者”,类型:“科幻”,语言:“俄语”,长度:“160”},
{名称:“外星人”,体裁:“科幻”,语言:“英语”,长度:“120”},
{名称:“俄罗斯方舟”,体裁:“戏剧”,语言:“俄语”,长度:“100”},
{名称:“心理”,体裁:“恐怖”,语言:“英语”,长度:“120”}
]
};
var viewModel=新电影模型(数据);
应用绑定(视图模型)
表td{
右边填充:20px;
}

电影名称
体裁
语言
长度

您需要查看所有过滤器选项,并应用每个有值的过滤器。过滤器的顺序无关紧要。这个想法是从未过滤的结果池中删除所有内容,直到只剩下适合所有过滤器的结果。