Как обновить Knockout ViewModel при использовании пользовательской привязки

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

Конкретный элемент управления, который я использую, — это SpinBox от Fuel UX: http://getfuelux.com/javascript.html#spinbox< /а>

Сама привязка данных прикреплена к обертывающему div, так как это контейнер для всего элемента управления:

<div id="daysToComplete-spinner" data-initialize="spinbox" class="spinbox input-group" style="width: 150px;" data-bind="spinbox: daysToComplete, spinboxOptions: {min: 0, max: 180 }">
    <input class="form-control spinbox-input" placeholder="Days">
    <div class="spinbox-buttons input-group-btn">
        <button type="button" class="btn btn-cancel spinbox-up">
            <span class="fa fa-angle-up"></span><span class="sr-only">Increase</span>
        </button>
        <button type="button" class="btn btn-cancel spinbox-down">
            <span class="fa fa-angle-down"></span><span class="sr-only">Decrease</span>
        </button>
    </div>
</div>

Я написал обработчик привязки, который, кажется, запускается и создает элемент управления, но есть пара вещей, которые трудно реализовать:

  • Я хочу зарегистрировать обработчик событий. Когда пользователь нажимает кнопку вверх или вниз (промежутки), мне нужно убедиться, что свойство ViewModel обновлено новым значением. Я пытался использовать valueAccessor(), но он дает мне значение, а не наблюдаемое свойство, которое я ожидал (после прочтения документов на сайте ko).
  • Я хочу убедиться, что если пользователь вводит число в поле ввода, свойство ViewModel обновляется. Привязка данных находится в div, поэтому я предполагаю, что нокаут не «знает», что ввод внутри div изменился... как мне это сделать? Тот же обработчик событий?

Вот что у меня есть на данный момент в моем обработчике:

$(function () {
    ko.bindingHandlers.spinbox = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

            var options = allBindingsAccessor().spinboxOptions || {};

            $(element).spinbox(options);

            var value = ko.utils.unwrapObservable(valueAccessor());

            if (value) {
                $(element).spinbox("value", value);
            }

            ko.utils.registerEventHandler(element, "changed.fu.spinbox", function (event, value) {
                var modelValue = valueAccessor(),
                modelValue(value); //it crashes here "not a function"

            });
        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            $(element).spinbox("value", value);

            console.log(value);
        }
    };
});

Любое руководство относительно того, что мне не хватает, будет оценено по достоинству.


person Ray    schedule 19.05.2016    source источник


Ответы (1)


Я не знаю, как выглядит ваша модель представления, но можете ли вы убедиться, что вы не перезаписываете наблюдаемое значение во время предыдущих операций.

Если в какой-то момент вы сделали что-то вроде этого:

viewmodel.daysToComplete = 4

Тогда свойство daysToComplete больше не является наблюдаемым. В результате valueAccessor() вернет не наблюдаемое, а 4, что вы, кажется, описываете.

person Regis    schedule 19.05.2016