如何在使用自定义绑定时更新Knockout ViewModel

时间:2016-05-19 17:06:25

标签: javascript knockout.js viewmodel fuelux

我正在尝试将一个旋转框(带有递增和递减按钮的输入)连接到KO,但是当我确保我的ViewModel在用户与控件交互时正确更新时,我遇到了一些麻烦。

我使用的具体控件是Fuel UX的SpinBox: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);
        }
    };
});

任何有关我缺少的指导都将不胜感激。

1 个答案:

答案 0 :(得分:4)

我不知道您的视图模型是什么样的,但是您可以确保在以前的操作过程中不会用值覆盖observable。

如果在某些时候你做过类似的事情:

viewmodel.daysToComplete = 4

然后daysToComplete属性不再是可观察的。 因此,valueAccessor()不会返回一个observable,而是4,这就是你似乎要描述的内容。