Связывание с Knockout.js с параметрами
У меня есть эта небольшая ViewModel:
function BooksViewModel() {
var self = this;
self.books = ko.observableArray(library);
self.findByLanguage = function(lang) {
self.books = ko.computed(function() {
return ko.utils.arrayFilter(library, function(book) {
return book.language() === lang;
});
});
};
}
Метод findByLanguage фильтрует массив по языку. В представлении im tryign реализует это следующим образом:
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#" data-bind="click: findByLanguage('C')">C</a></li>
<li><a tabindex="-1" href="#" data-bind="click: findByLanguage('Cpp')">C++</a></li>
</ul>
Я пытаюсь повторно использовать функцию, вызывая там параметр языка. Но если я передаю функцию с круглыми скобками по привязке данных, она автоматически вызывается.
Как я могу это сделать?
Ответы
Ответ 1
Вам может быть интересен несколько иной подход, который добавляет дополнительные поля в вашу модель просмотра.
http://jsfiddle.net/jearles/RN9Dw/
Добавив languages
в Model View, вы можете использовать Knockout для визуализации меню, а привязка click
будет автоматически передавать язык, на который была нажата функция обработчика. Кроме того, добавление selectedLanguage
в качестве наблюдаемого позволяет вычислять books
при выборе или очистке языка.
HTML
<ul class="dropdown-menu" data-bind="foreach: languages">
<li><a tabindex="-1" href="#" data-bind="text: $data, click: $root.filterByLanguage"></a></li>
</ul>
<button data-bind="click: showAll">Show All</button>
<div data-bind="foreach: books">
<p><span data-bind="text: name"></span>, <span data-bind="text: language"></span></p>
</div>
JS
function BooksViewModel() {
var self = this;
self.languages = ko.observableArray(['C', 'C++']);
self.selectedLanguage = ko.observable();
self.library = [{name: 'Book A', language: 'C'}, {name: 'Book B', language: 'C++'}];
self.books = ko.computed(function() {
return ko.utils.arrayFilter(self.library, function(book) {
return self.selectedLanguage() == null ||
book.language === self.selectedLanguage();
})
});
self.showAll = function() {
self.selectedLanguage(null);
}
self.filterByLanguage = function(lang) {
self.selectedLanguage(lang);
};
}
ko.applyBindings(new BooksViewModel());
Ответ 2
Самый простой способ сделать это - обернуть это в функцию, которая выполняется только при нажатии, например:
<li><a tabindex="-1" href="#" data-bind="click: function () {findByLanguage('C')}">
В качестве альтернативы вы можете использовать контекст привязки, чтобы сделать трюк.
<li><a tabindex="-1" href="#" data-bind="click: findByLanguage.bind('C')">
Ниже приведен пример привязки кликов с помощью JS Fiddle (http://jsfiddle.net/uFyaP/1/)
Ответ 3
Я знаю, что вопрос старый, но если кому-то интересно, согласно docs, первым параметром должен быть viewModel, затем он работает как ожидалось.
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#" data-bind="click: findByLanguage.bind($data, 'C')">C</a></li>
<li><a tabindex="-1" href="#" data-bind="click: findByLanguage.bind($data, 'Cpp')">C++</a></li>
</ul>