我正在创建一个电子商务网站,我有一个类型产品模型,其中包含我的客户希望销售的每种产品的所有信息。该产品模型被推送到一个可观察的阵列,通过foreach:在屏幕上显示给用户:这一切都很好。
我希望有一些控件,例如复选框/单选按钮,可以在屏幕上过滤数组。例如,按颜色或大小。阅读教程,如果处理数字或单词的线性数组,这是很容易做到的。我无法将其转换为使用模型。我想选择例如颜色为红色,然后可观察数组将过滤到数组中product.color = red的位置。
非常感谢任何帮助。
答案 0 :(得分:1)
对于我们这些想要帮助的人来说,更好地了解一下你想要做什么是非常有用的。请在将来提问时分享您的代码,因为这有助于我们更好地帮助您并减少我们的猜测。无论哪种方式,我都继续创建了一个jsfiddle来演示我认为你可能想要的东西。
此演示使用knockout 可计算来处理过滤。可计算性是由某些给定函数计算的可观察量。在我的例子中,我只是使用基本JS数组函数执行一些过滤(使用 ko.utils 函数可能更好,但我想对那些不熟悉淘汰赛的人保持清晰。)
<强> JS:强>
function FilterViewModel() {
var self = this;
self.products = ko.observableArray([
{ name: 'widget', color: 'blue', size: 'large' },
{ name: 'wigglit', color: 'red', size: 'large' },
{ name: 'gadget', color: 'yellow', size: 'small' },
{ name: 'wadget', color: 'blue', size: 'large' },
{ name: 'wizzle', color: 'blue', size: 'small' },
{ name: 'fizzle', color: 'green', size: 'small' },
{ name: 'gigglit', color: 'blue', size: 'small' },
{ name: 'fidget', color: 'red', size: 'large' },
{ name: 'midget', color: 'red', size: 'large' },
{ name: 'madget', color: 'blue', size: 'large' },
]);
self.selectedColor = ko.observableArray('');
self.selectedSize = ko.observable('');
self.filteredProducts = ko.computed(function () {
return self.products().filter(function (value) {
var isInSet = true;
// if the size doesn't match, don't include this one
if(self.selectedSize() != '' && self.selectedSize() != null &&
self.selectedSize() != value.size)
isInSet = false;
// if the colors don't match, don't include this one
if(self.selectedColor() != '' &&
self.selectedColor() != null &&
self.selectedColor() != value.color) {
isInSet = false;
}
return isInSet;
});
});
self.colorOptions = ko.computed(function() {
var colorChoices = self.products().map(function(value) {
return value.color;
}).filter(function(elem, pos, self) {
return self.indexOf(elem) == pos;
});
//combine a blank choice and the colors from products
return (['']).concat(colorChoices);
});
self.sizeOptions = ko.computed(function() {
var sizeChoices = self.products().map(function(value) {
return value.size;
}).filter(function(elem, pos, self) {
return self.indexOf(elem) == pos;
});
//combine a blank choice and the sizes from products
return (['']).concat(sizeChoices);
});
}
var viewModel = new FilterViewModel();
ko.applyBindings(viewModel);
<强> HTML:强>
<div class="blockItem">
<p>Color:
<select data-bind="options: colorOptions, value: selectedColor"></select>
</p>
<p>Size:
<select data-bind="options: sizeOptions, value: selectedSize"></select>
</p>
</div>
<div class="blockItem">
<p><b>PRODUCTS</b></p>
<!-- ko foreach: filteredProducts -->
<p class="blockItem">
<b>Name:</b> <span data-bind="text: $data.name"></span>,
<b>Color:</b> <span data-bind="text: $data.color"></span>,
<b>Size:</b> <span data-bind="text: $data.size"></span>
</p>
<!-- /ko -->
</div>
<强> CSS:强>
.blockItem {
border: 2px black solid;
padding: 2px;
}
答案 1 :(得分:0)
您可以使用ko.utils函数来过滤数组,该页面上的示例只有一个过滤器。如果你想扩展它以过滤不同的字段,这不会太难,但正如Aeolos在评论中所说的那样,我们需要你发布一些代码才能提供帮助。
但是,你可以创建一个Filter对象,其中包含要过滤的字段名称和过滤器值,并将每个活动过滤器添加到observableArray过滤器中:
//filter the items using the filter text
viewModel.filteredItems = ko.computed(function() {
if (filters().length === 0) {
return this.items();
} else {
var results = this.items();
for(var i = 0; i < filters().length; i++)
{
var filter = filters()[i];
results = ko.utils.arrayFilter(results, function(item) {
return ko.utils.stringStartsWith(item[filter.name]().toLowerCase(), filter.value);
});
}
return results;
}
}, viewModel);
这没有经过任何测试,但它可能会让你知道该怎么做。