假设我有电影阵列,如果我想按类型过滤我可以做这样的事情
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分钟的俄罗斯动作片或动作片长度等?
答案 0 :(得分:2)
您需要根据提供的每个过滤器逐步构建过滤列表。至于过滤器本身,它们应该由observableArray中的一个observable或全部表示。这很重要,因为它会在您更改过滤器时触发计算更新。
示例:
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;
});
此代码将遍历每个过滤器,获取最新的过滤列表,并仅保留满足所有条件的项目。
答案 1 :(得分:0)
过滤结果是针对值的组合,可以通过迭代所有可能的过滤器,应用用户选择的过滤器,并从结果中删除不适合过滤器的项目来完成。应用过滤器的顺序无关紧要。这些项目必须符合所有条件才能成为有效结果,因此您可以在不合适的情况下立即将它们丢弃。
这是一些伪代码。
# 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
答案 2 :(得分:0)
我知道这是个老话题,但是最近我遇到了同样的问题,这是针对您的电影模型修改的解决方案。您也可以在这里查看:jsfiddle
var MoviesModel = function(data) {
var self = this;
self.Genres = ko.observableArray(data.genres);
self.Genres.unshift("All");
self.filterGenre = ko.observable("All");
self.Languages = ko.observableArray(data.languages);
self.Languages.unshift("All");
self.filterLanguage = ko.observable("All");
self.Lengths = ko.observableArray(data.lengths);
self.Lengths.unshift("All");
self.filterLength = ko.observable("All");
self.movies = ko.observableArray(data.movies);
self.filteredMovies = ko.computed(function() {
var filteredArray = ko.utils.arrayFilter(self.movies(), function(item) {
return (
(item.genre == self.filterGenre() || self.filterGenre() == "All") &&
(item.language == self.filterLanguage() || self.filterLanguage() == "All") &&
(item.length == self.filterLength() || self.filterLength() == "All")
);
});
return filteredArray;
});
};
var data = {
genres: ["Drama", "Horror", "Sci-Fi"],
languages: ["English", "Russian"],
lengths: ["100", "120", "140", "160"],
movies: [
{ name: "Godfather", genre: "Drama", language: "English", length: "160" },
{ name: "The shining", genre: "Horror", language: "English", length: "140"},
{ name: "Stalker", genre: "Sci-Fi", language: "Russian", length: "160" },
{ name: "Alien", genre: "Sci-Fi", language: "English", length: "120" },
{ name: "Russiam ark", genre: "Drama", language: "Russian", length: "100" },
{ name: "Psycho", genre: "Horror", language: "English", length: "120" }
]
};
var viewModel = new MoviesModel(data);
ko.applyBindings(viewModel);
table td {
padding-right: 20px;
}
<table>
<thead>
<tr>
<td>Movie name</td>
<td>Genre</td>
<td>Language</td>
<td>Length</td>
</tr>
<tr>
<td></td>
<td>
<select data-bind="options: Genres, value: filterGenre"></select>
</td>
<td>
<select
data-bind="options: Languages, value: filterLanguage"
></select>
</td>
<td>
<select data-bind="options: Lengths, value: filterLength"></select>
</td>
</tr>
</thead>
<tbody data-bind="foreach: filteredMovies">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: genre"></td>
<td data-bind="text: language "></td>
<td data-bind="text: length"></td>
</tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>