使用knockoutjs过滤有界项

本文关键字:过滤 knockoutjs 使用 | 更新日期: 2023-09-27 18:04:47

在KnockoutJS提供给我之前的问题项目选择MVC视图的帮助下,我能够实现我在那个时间点之后的目标。大家都知道新的需求很快就会出现,现在就是这样。我需要显示一个组合框,它应该过滤(更改)所有可用项目的列表。在我的示例选择列表中,我参考并尝试了许多示例。

我的简单观点:

<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>

ViewModel:

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显示的列表都不会刷新。我甚至尝试了其他方式显示在上一个问题项目选择MVC视图与KnockoutJS,在更新部分。

我怀疑这是由于availableItems和selectedItems连接在一起的方式,但我不确定什么是错的。

我看到文本框击键,视图模型filteredItems正在被调用(注意到在我的jsfiddle chrome中的错误,虽然,可能是问题,相同的功能在其他jsfiddle工作)。我完全匹配了库,没有帮助来避免这些错误。

请帮我解决这个问题

使用knockoutjs过滤有界项

在您的JsFiddle中,问题是ko.utils.stringStartsWith不可用。这是一个用于删除的内部函数,当您使用缩小版本时,该函数将被删除。

最好的解决方案是编写自己的startsWith函数,或者使用谷歌找到一个,或者如果您正在使用一个,则从其他库中获取一个。