Подтвердить что ты не робот

Перехват блокировки нокаутом на 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-странице.

4b9b3361

Ответ 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' в вызываемой функции.