背景:我正在将遗留系统中的javascript逻辑转移到淘汰赛以获得更多结构,并且将来必须编写更少的代码。由于时间限制,我只能将部分代码移到每次部署之间进行淘汰。
问题:部分数据是由遗留代码生成的,有些数据是由淘汰生成的,而且我在创建淘汰逻辑时遇到问题需要处理以下情况(见下文)代码片段和JSFiddle链接到相同的代码)。产品单选按钮不是由淘汰产生的,但是产品列表是。过滤商品列表的关键按钮就像我想要的那样,但我已经设法弄清楚如何仅获得产品1 下列出的产品1的优惠,而且只提供产品2列在产品2 下。有人可以提供帮助吗?
我认为如果产品标题是根据淘汰视图模型中的数据生成的,那么我的问题就不会那么难以解决,但正如您所看到的那样,并非如此。
https://jsfiddle.net/b6er4wke/3/
function myViewModel() {
var self = this;
self.wrappedProducts = ko.observableArray();
self.availableOffers = ko.observableArray();
self.filterKey = ko.observable(1);
filteredItems = ko.computed(function() {
return ko.utils.arrayFilter(self.availableOffers(), function (offer) {
var isCorrectKey = offer.key == self.filterKey();
return (isCorrectKey);
});
});
self.filter = function(keyFilter) {
self.filterKey(keyFilter);
};
(function() {
// Products
self.wrappedProducts.push({"prod":"1"});
self.wrappedProducts.push({"prod":"2"});
// Offers
self.availableOffers.push({"name": "offer1", "key": "1", "prod": 1});
self.availableOffers.push({"name": "offer2", "key": "2", "prod": 1});
self.availableOffers.push({"name": "offer3", "key": "2", "prod": 2});
})();
}
var viewModel = new myViewModel();
ko.applyBindings(viewModel);

ul, h4 {margin-top: 0px; margin-bottom:0px;}
label {font-weight:bold;}

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h4>All products</h4>
<ul data-bind="foreach: wrappedProducts">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<h4>Available offers</h4>
<ul data-bind="foreach: availableOffers">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<div>
<button data-bind="click: function() {filter(1);}">key1</button>
<button data-bind="click: function() {filter(2);}">key2</button>
filterKey = <span data-bind="text: filterKey"></span>
</div>
<hr>
<label for="prod1">Product 1</label>
<ul data-bind="foreach: filteredItems">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<label for="prod2">Product 2</label>
<ul data-bind="foreach: filteredItems">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
&#13;
答案 0 :(得分:2)
Knockout会自动将您的绑定表达式包装在computed
中,因此您实际上只需将filteredItems
作为常规函数并使用要显示为参数的产品调用它:
filteredItems = function filteredItems(product) {
return ko.utils.arrayFilter(self.availableOffers(), function (offer) {
return offer.key == self.filterKey() && offer.prod == product;
});
};
<label for="prod1">Product 1</label>
<ul data-bind="foreach: filteredItems(1)">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<label for="prod2">Product 2</label>
<ul data-bind="foreach: filteredItems(2)">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
并在availableOffers
更改时自动更新。
function myViewModel() {
var self = this;
self.wrappedProducts = ko.observableArray();
self.availableOffers = ko.observableArray();
self.filterKey = ko.observable(1);
filteredItems = function filteredItems(product) {
return ko.utils.arrayFilter(self.availableOffers(), function (offer) {
return offer.key == self.filterKey() && offer.prod == product;
});
};
self.filter = function(keyFilter) {
self.filterKey(keyFilter);
};
(function() {
// Products
self.wrappedProducts.push({"prod":"1"});
self.wrappedProducts.push({"prod":"2"});
// Offers
self.availableOffers.push({"name": "offer1", "key": "1", "prod": 1});
self.availableOffers.push({"name": "offer2", "key": "2", "prod": 1});
self.availableOffers.push({"name": "offer3", "key": "2", "prod": 2});
})();
}
var viewModel = new myViewModel();
ko.applyBindings(viewModel);
&#13;
ul, h4 {margin-top: 0px; margin-bottom:0px;}
label {font-weight:bold;}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h4>All products</h4>
<ul data-bind="foreach: wrappedProducts">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<h4>Available offers</h4>
<ul data-bind="foreach: availableOffers">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<div>
<button data-bind="click: function() {filter(1);}">key1</button>
<button data-bind="click: function() {filter(2);}">key2</button>
filterKey = <span data-bind="text: filterKey"></span>
</div>
<hr>
<label for="prod1">Product 1</label>
<ul data-bind="foreach: filteredItems(1)">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<label for="prod2">Product 2</label>
<ul data-bind="foreach: filteredItems(2)">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
&#13;
答案 1 :(得分:0)
嗯,你只是显示相同计算结果。那么,这就是为什么在Prod 1和Prod 2下你获得相同的结果。如果您想按产品和密钥进行过滤,那么您需要两个可以为您过滤的计算函数。
您在arrayFilter中缺少的代码是:
var isCorrectKey = offer.key == self.filterKey();
var isCorrectProduct = offer.prod == 2;
return isCorrectKey && isCorrectProduct;
您必须检查产品和密钥。
function myViewModel() {
var self = this;
self.wrappedProducts = ko.observableArray();
self.availableOffers = ko.observableArray();
self.filterKey = ko.observable(1);
filteredItemsKey1 = ko.computed(function () {
return ko.utils.arrayFilter(self.availableOffers(), function (offer) {
var isCorrectKey = offer.key == self.filterKey();
var isCorrectProduct = offer.prod == 1;
return isCorrectKey && isCorrectProduct;
});
});
filteredItemsKey2 = ko.computed(function () {
return ko.utils.arrayFilter(self.availableOffers(), function (offer) {
var isCorrectKey = offer.key == self.filterKey();
var isCorrectProduct = offer.prod == 2;
return isCorrectKey && isCorrectProduct;
});
});
self.filter = function(keyFilter) {
self.filterKey(keyFilter);
};
(function() {
// Products
self.wrappedProducts.push({"prod":"1"});
self.wrappedProducts.push({"prod":"2"});
// Offers
self.availableOffers.push({"name": "offer1", "key": "1", "prod": 1});
self.availableOffers.push({"name": "offer2", "key": "2", "prod": 1});
self.availableOffers.push({"name": "offer3", "key": "2", "prod": 2});
})();
}
var viewModel = new myViewModel();
ko.applyBindings(viewModel);
&#13;
ul, h4 {margin-top: 0px; margin-bottom:0px;}
label {font-weight:bold;}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h4>All products</h4>
<ul data-bind="foreach: wrappedProducts">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<h4>Available offers</h4>
<ul data-bind="foreach: availableOffers">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<div>
<button data-bind="click: function() {filter(1);}">key1</button>
<button data-bind="click: function() {filter(2);}">key2</button>
filterKey = <span data-bind="text: filterKey"></span>
</div>
<hr>
<label for="prod1">Product 1</label>
<ul data-bind="foreach: filteredItemsKey1">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
<label for="prod2">Product 2</label>
<ul data-bind="foreach: filteredItemsKey2">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
&#13;