根据我之前的问题Item selection MVC view with KnockoutJS提供的帮助,我能够实现我在那个时间点所追求的目标。众所周知,新的要求将会更快到来,而且就在这里。我需要显示一个组合框,它应该过滤(更改)总可用项列表。我在我的示例Selection List中提到并尝试过很多例子。
我的简单观点:
<h3>Filter Available Items By Name: </h3>
<p>Type letters: <input data-bind="value: filter, valueUpdate: 'afterkeydown'" /></p>
<div id='contactsList'>
<span data-bind="visible: availableItems().length > 0">Available countries: </span>
<ul data-bind="foreach: filteredItems, visible: availableItems().length > 0">
<li>
<input type="checkbox" data-bind="checkedValue: $data, checked: $root.selectedItems" />
<span data-bind="text: title"></span>
</li>
</ul>
<span data-bind="visible: selectedItems().length > 0">Selected countries: </span>
<ul data-bind="foreach: selectedItems, visible: selectedItems().length > 0">
<li>
<span data-bind="text: title"></span>
<a href="#" data-bind="click: $parent.removeItem">Delete</a>
</li>
</ul>
</div>
视图模型:
var initialData = [
{
availableItems: [
{ title: "US", isSelected: true },
{ title: "Canada", isSelected: false },
{ title: "India", isSelected: false }]
},
{
selectedItems: [
{ "title": "US" },
{ "title": "Canada" }
]
}
];
function Item(titleText, isSelected) {
this.title = ko.observable(titleText);
this.isSelected = ko.observable(isSelected);
}
var SelectableItemViewModel = function (items) {
// Data
var self = this;
self.filter = ko.observable("");
self.availableItems = ko.observableArray(ko.utils.arrayMap(items[0].availableItems, function (item) {
return new Item(item.title, item.isSelected);
}));
self.selectedItems = ko.observableArray(ko.utils.arrayMap(items[1].selectedItems, function (item) {
return ko.utils.arrayFirst(self.availableItems(), function (itm){
return item.title == itm.title();
});
}));
//filter the items using the filter text
self.filteredItems = ko.dependentObservable(function () {
debugger;
var filter = this.filter().toLowerCase();
if (!filter) {
return this.availableItems();
} else {
return ko.utils.arrayFilter(this.availableItems(), function (item) {
return ko.utils.stringStartsWith(item.title().toLowerCase(), filter);
});
}
}, self);
// Operations
self.removeItem = function (removedItem) {
self.selectedItems.remove(removedItem);
};
}
var vm = new SelectableItemViewModel(initialData);
$(document).ready(function () {
ko.applyBindings(vm);
});
为简单起见,我只是想在文本框中的按键上实现它(我希望一旦我实现了组合框项目选择更改将顺利运行)。
问题是,无论如何,使用filteredItems显示的列表都不会刷新。我甚至在更新部分尝试了上一个问题Item selection MVC view with KnockoutJS中显示的其他方式。
我怀疑这是由于availableItems和selectedItems连接在一起的方式,但我不确定是什么错误。
我在文本框按键上看到,viewmodel filteredItems被调用(虽然注意到我的jsfiddle中的chrome中的错误,可能是问题,同样的功能在其他jsfiddle中工作)。我确实完全匹配了这些库,没有任何帮助来避免这些错误。
请帮我解决这个问题。
答案 0 :(得分:3)
在你的JsFiddle中,问题是ko.utils.stringStartsWith
不可用。这是一个敲除的内部函数,当你使用缩小版本时会删除它。
最好的解决方案是编写自己的startsWith
函数,或者使用google查找一个函数,或者如果您使用的话,可以从另一个库中获取一个函数。