Перехват блокировки нокаутом на applyBindings
Недавно я выделил ViewModel для отдельного файла JavaScript.
var Report = (function($) {
var initialData = [];
var viewModel = {
reports: ko.observableArray(initialData),
preview: function(path) {
// preview report
},
otherFunctions: function() {}
};
return viewModel;
})(jQuery);
Вот код, связанный с HTML и Knockout
<script type="text/javascript" src="path/to/report/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
ko.applyBindings(Report, document.body);
});
</script>
В пользовательском интерфейсе HTML есть кнопка, по которой клик привязывается к функции предварительного просмотра в модели представления
<input type="button" name="Preview" id="Preview" class="btnPreview"
data-bind="click: Report.preview('url/to/report')" />
Проблема вызывается метод, когда следующая строка выполняется в функции $(document).ready()
ko.applyBindings(Report, document.body);
Это означает, что пользователь не нажимает кнопку предварительного просмотра. Что может быть причиной такого поведения? Весь материал отлично работал, когда я просматривал модельный JavaScript на самой HTML-странице.
Ответы
Ответ 1
Причина в том, что вы действительно вызываете функцию предварительного просмотра (поскольку запись functionName
означает обращение к функции, запись functionName()
означает вызов ее).
Итак, data-bind="click: Report.preview"
будет работать как ожидалось, но не передавая параметр.
Как руководство указывает (по другому вопросу, но это все еще применяется):
Если вам нужно передать больше параметров, один из способов сделать это - обернуть обработчик в литерал функции, который принимает параметр, как в этом примере:
<button data-bind="click: function(data, event) { myFunction(data, event, 'param1', 'param2') }">
Click me
</button>
или в вашем случае:
data-bind="click: function() { Report.preview('url/to/report') }"
Другим решением было бы сделать предварительный просмотр() возвратом функции (практически на самом деле):
preview: function(path) {
return function() {
// ...
}
}
Ответ 2
Другое решение - использовать конструкцию "bind":
data-bind="click: Report.preview.bind($data, 'url/to/report')"
где первый параметр bind() станет 'this' в вызываемой функции.