淘汰赛产品过滤
Knockout product filtering
我正在尝试使用 Knockout 创建产品过滤系统。我将收到单独的 JSON 文件 - 一个包含产品(和所有相关属性)和一个单独的文件用于每个单独的过滤器。我需要在页面加载时显示所有结果,然后使用过滤器复选框过滤掉其他选项。我已经设置了一个基本的 fiddle 来复制我的结构:http://jsfiddle.net/nimaek/0kbmchxe/4/ - 在真实版本中,每个对象都将从 JSON 提供。
我看过一些教程,我认为 ko.utils.arrayfilter 可能是我需要的解决方案 - 我还认为最好的方法可能是在我的对象中包含一个过滤函数,如下所示。但这两种想法都可能是错误的。
var colorFilters = [
{id:"1", color: "white", filter: function(product){return product.color == "white";}},
{id:"2", color: "black", filter: function(product){return product.color == "black";}},
{id:"3", color: "blue", filter: function(product){return product.color == "blue";}}
];
使用此功能的最佳方法是什么?不用说,我只是在了解 Knockout,尽管我在网上找到的一些示例看起来很棒,但我仍在努力弄清楚如何将它们复制到我自己的项目中。
谢谢。
更新
只是为了进一步说明我的问题,我已经使用 jQuery 复制了我正在寻找的功能:http://jsfiddle.net/nimaek/0kbmchxe/6/ - 是否有 better/more 使用 Knockout 处理此问题的高效方法?
不确定这是否是 'best' 方法,但是如果您可以在过滤器对象中使用过滤器函数,那么您可以这样做。
var viewModel = function () {
var self = this;
var products = [
{title:"Product 1", price: 100, color: "white"},
{title:"Product 2", price: 200, color: "black"},
{title:"Product 3", price: 200, color: "blue"},
{title:"Product 4", price: 400, color: "white"},
{title:"Product 5", price: 400, color: "blue"}
];
self.allProducts = ko.observableArray(products);
self.filteredProducts = ko.observableArray(products);
var colorFilters = [
{id:"1", color: "white", filter: function(product){return product.color == "white";}},
{id:"2", color: "black", filter: function(product){return product.color == "black";}},
{id:"3", color: "blue", filter: function(product){return product.color == "blue";}}
];
self.allColors = ko.observableArray(colorFilters);
var priceFilters = [
{id:"1", price: 100,filter: function(product){return product.price == 100;}},
{id:"2", price: 200,filter: function(product){return product.price == 200;}},
{id:"3", price: 400,filter: function(product){return product.price == 400;}}
];
self.allPrices = ko.observableArray(priceFilters);
self.selectedFilters = ko.observableArray();
self.addFilter = function(filter){
if(self.selectedFilters.indexOf(filter)==-1)
self.selectedFilters.push(filter);
else self.selectedFilters.remove(filter);
updateProducts();
return true;
};
function updateProducts(){
var p = [];
if(self.selectedFilters().length==0)
return self.filteredProducts(self.allProducts());
ko.utils.arrayForEach(self.allProducts(), function(product){
//apply filters
ko.utils.arrayForEach(self.selectedFilters(), function(filter){
if(filter.filter(product) && p.indexOf(product)==-1)
p.push(product);
});
});
self.filteredProducts(p);
}
};
ko.applyBindings(new viewModel());
jsFiddle:http://jsfiddle.net/newuserjs/4722mLch/(显示带有任何过滤器的产品)
更新
jsFiddle:http://jsfiddle.net/newuserjs/4722mLch/2/(显示同时匹配 price
AND color
过滤器的产品)
最好使用计算来完成过滤。
var colorFilters = ['white','black','blue'];
this.allColors = ko.observableArray(colorFilters);
this.selectedColors = ko.observableArray();
this.filteredProducts = ko.computed(function () {
var self = this;
if (self.selectedColors().length == 0) return this.allProducts();
return ko.utils.arrayFilter(this.allProducts(), function (product) {
return self.selectedColors().indexOf(product.color) >= 0;
}, this);
}, this);
我已经 updated your fiddle 进行了颜色过滤,并将价格过滤作为练习留给您。 :)
我正在尝试使用 Knockout 创建产品过滤系统。我将收到单独的 JSON 文件 - 一个包含产品(和所有相关属性)和一个单独的文件用于每个单独的过滤器。我需要在页面加载时显示所有结果,然后使用过滤器复选框过滤掉其他选项。我已经设置了一个基本的 fiddle 来复制我的结构:http://jsfiddle.net/nimaek/0kbmchxe/4/ - 在真实版本中,每个对象都将从 JSON 提供。
我看过一些教程,我认为 ko.utils.arrayfilter 可能是我需要的解决方案 - 我还认为最好的方法可能是在我的对象中包含一个过滤函数,如下所示。但这两种想法都可能是错误的。
var colorFilters = [
{id:"1", color: "white", filter: function(product){return product.color == "white";}},
{id:"2", color: "black", filter: function(product){return product.color == "black";}},
{id:"3", color: "blue", filter: function(product){return product.color == "blue";}}
];
使用此功能的最佳方法是什么?不用说,我只是在了解 Knockout,尽管我在网上找到的一些示例看起来很棒,但我仍在努力弄清楚如何将它们复制到我自己的项目中。
谢谢。
更新 只是为了进一步说明我的问题,我已经使用 jQuery 复制了我正在寻找的功能:http://jsfiddle.net/nimaek/0kbmchxe/6/ - 是否有 better/more 使用 Knockout 处理此问题的高效方法?
不确定这是否是 'best' 方法,但是如果您可以在过滤器对象中使用过滤器函数,那么您可以这样做。
var viewModel = function () {
var self = this;
var products = [
{title:"Product 1", price: 100, color: "white"},
{title:"Product 2", price: 200, color: "black"},
{title:"Product 3", price: 200, color: "blue"},
{title:"Product 4", price: 400, color: "white"},
{title:"Product 5", price: 400, color: "blue"}
];
self.allProducts = ko.observableArray(products);
self.filteredProducts = ko.observableArray(products);
var colorFilters = [
{id:"1", color: "white", filter: function(product){return product.color == "white";}},
{id:"2", color: "black", filter: function(product){return product.color == "black";}},
{id:"3", color: "blue", filter: function(product){return product.color == "blue";}}
];
self.allColors = ko.observableArray(colorFilters);
var priceFilters = [
{id:"1", price: 100,filter: function(product){return product.price == 100;}},
{id:"2", price: 200,filter: function(product){return product.price == 200;}},
{id:"3", price: 400,filter: function(product){return product.price == 400;}}
];
self.allPrices = ko.observableArray(priceFilters);
self.selectedFilters = ko.observableArray();
self.addFilter = function(filter){
if(self.selectedFilters.indexOf(filter)==-1)
self.selectedFilters.push(filter);
else self.selectedFilters.remove(filter);
updateProducts();
return true;
};
function updateProducts(){
var p = [];
if(self.selectedFilters().length==0)
return self.filteredProducts(self.allProducts());
ko.utils.arrayForEach(self.allProducts(), function(product){
//apply filters
ko.utils.arrayForEach(self.selectedFilters(), function(filter){
if(filter.filter(product) && p.indexOf(product)==-1)
p.push(product);
});
});
self.filteredProducts(p);
}
};
ko.applyBindings(new viewModel());
jsFiddle:http://jsfiddle.net/newuserjs/4722mLch/(显示带有任何过滤器的产品)
更新
jsFiddle:http://jsfiddle.net/newuserjs/4722mLch/2/(显示同时匹配 price
AND color
过滤器的产品)
最好使用计算来完成过滤。
var colorFilters = ['white','black','blue'];
this.allColors = ko.observableArray(colorFilters);
this.selectedColors = ko.observableArray();
this.filteredProducts = ko.computed(function () {
var self = this;
if (self.selectedColors().length == 0) return this.allProducts();
return ko.utils.arrayFilter(this.allProducts(), function (product) {
return self.selectedColors().indexOf(product.color) >= 0;
}, this);
}, this);
我已经 updated your fiddle 进行了颜色过滤,并将价格过滤作为练习留给您。 :)