HTML代码
<input type="text" class="radius" placeholder="SerialNo" data-bind="textInput: fromSerialNo" />
<br/>
<select data-bind="options: filteredInventoryList,
optionsText: function(item) {
return item.Id + ' (' + item.SerialNo + ')';
},
selectedOptions: selectedEquipment
" size="5" multiple="multiple" style="width: 300px;"></select>
样本数据(简体):
var inventory = [{
Id: "1",
SerialNo: "00001"
},
{
Id: "2",
SerialNo: "00002"
},
{
Id: "3",
SerialNo: "10003"
},
{
Id: "4",
SerialNo: "10004"
}
];
淘汰代码:
function viewModel() {
var _root = this;
// User input serialNo for filtering
_root.fromSerialNo = ko.observable();
// selectedOptions of the select list
_root.selectedEquipment = ko.observableArray();
// parent list of all equipment
_root.fromInventoryList = ko.observableArray(inventory);
// filtered list based on serialNo user input (should including the previously selected items)
_root.filteredInventoryList = ko.computed(function() {
var filteredList = ko.observableArray(null);
if (!_root.fromSerialNo()) {
// This works perfect, allows the user to select one or more item from the list.
return _root.fromInventoryList();
}
else {
// The following works and allow users to filter the parent list of equipment
// Only show items that begin with the SerialNo entered
filteredList(ko.utils.arrayFilter(_root.fromInventoryList(), function (item) {
return item.SerialNo.startsWith(_root.fromSerialNo());
}));
return filteredList();
}
});
}
就根据用户输入的序列号过滤列表而言,一切工作都很好。例如此处https://jsfiddle.net/JohnnyCodes/5h9pnqLg/。
用例:
问题是,就像有某种递归引用一样,列表开始变得晦涩难懂。
输入1进行过滤,然后将其更改为0,然后将其更改回1
这是一个示例,https://jsfiddle.net/JohnnyCodes/cs4z9xpg/5/
相当有些东西,这是我忽略的真正简单而愚蠢的东西,但我已经兜圈子了一段时间。不会介意另一双眼睛。
谢谢
问题是与以下行
// Default the list to include the selected items.
filteredList(_root.selectedEquipment());
可观察对象使用标准数组作为其基础数据,但是当您使用现有数组初始化可观察对象时,可观察对象将使用该数组作为基础数组而不是创建新数组,并且保留对其的所有引用。这意味着即使您的filteredList
var具有新的作用域,在下一个循环中,它也会被指向相同的现有数组(selectedEquipment),并且该数组在上一次重新计算后仍具有值。
更改该行,以便将项目添加到该函数顶部创建的可观察对象中,而无需重新使用根级selectedEquipment数组应可解决以下问题:
ko.utils.arrayPushAll(filteredList, _root.selectedEquipment());