Фильтрация ограниченного элемента с помощью knockoutjs

0

После помощи, предоставленной моему предыдущему вопросу. Выбор позиции MVC с помощью KnockoutJS, я смог добиться того, что был в этот момент. Было известно, что новое требование наступит раньше, и вот оно. Мне нужно отобразить combobox, который должен фильтровать (изменять) список всех доступных элементов. Есть много примеров, которые я упомянул и попробовал в моем примере 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>

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);
});

Для простоты я просто пытаюсь добиться этого нажатием клавиши в текстовом поле (я надеюсь, что когда я достиг, что изменение выбора элемента списка будет работать плавно).

Проблема в том, что неважно, список, отображаемый с использованием фильтрованных элементов, не обновляется. Я даже пытался использовать другие способы, показанные в предыдущем вопросе. Выбор позиции MVC-просмотр с помощью KnockoutJS в разделе обновления.

Я подозреваю, что это связано с тем, как доступны. Элементы и отдельные элементы связаны друг с другом, но я не уверен, что случилось.

Я вижу в текстовом поле нажатия клавиши, viewmodel filterItems получает вызов (заметила ошибку в chrome в моей jsfiddle, хотя, может быть, проблема, такая же функция работает и в других jsfiddle). Я точно соответствовал библиотекам без помощи, чтобы избежать этих ошибок.

Пожалуйста, помогите мне решить эту проблему.

Теги:
asp.net-mvc
knockout.js

1 ответ

3
Лучший ответ

В вашей JsFiddle проблема в том, что ko.utils.stringStartsWith недоступен. Это внутренняя функция для нокаута, которая удаляется при использовании мини-версии.

Лучшее решение - написать свою собственную функцию startsWith или найти ее с помощью google или получить ее из другой библиотеки, если вы ее используете.

  • 0
    Спорт дальше !!! Я изменил внешние ресурсы на отладочную версию, и все заработало, как я и ожидал. Огромное спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню