自定义bindingHandler的返回值/可观察

时间:2015-06-01 10:24:32

标签: knockout.js

我无法为此找到解决方案。

我正在尝试为html元素 div 标记上的click事件创建自定义bindingHandler。

// custom bindingHandler and observable
<div data-bind="OnClickEvent: HasBeenClicked"></div>
// to show observable's true/false value
<span data-bind="text: 'Observable: ' + HasBeenClicked()"></span>

此bindingHandler执行它所假设的操作,如果单击 div ,文本将更改。但是,observable表示 false

ko.bindingHandlers.OnClickEvent = {
    update: function (element, valueAccessor) {

        $(element).text('Click Here: false');

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

        $(element).on('click', function () {

            observable = !observable;

            if (observable) {
                $(element).text('Click Here: true');
            } else {
                $(element).text('Click Here: false');
            }
        });
    }
}


function ViewModel() {
    var self = this;
    self.HasBeenClicked = ko.observable(false);
}

ko.applyBindings(new ViewModel());

如何将可观察的 HasBeenClicked 设置为在每次点击时切换为true / false,如文字?

1 个答案:

答案 0 :(得分:2)

我第二次@ nemesv对快速修复的评论以及你的绑定看起来有点奇怪的事实。我会把它扩展到答案因为我需要房间。

首先,快速修复:

  • 我认为你所写的绑定类型更适合在init部分内完成你的工作;
  • 您需要回写valueAccessor来更改observable的值(我在下面显示快速和脏的演示);

这是一个有效的例子:

ko.bindingHandlers.OnClickEvent = {
    init: function (element, valueAccessor) {

        $(element).text('Click Here: false');

        var observable = ko.utils.unwrapObservable(valueAccessor());
        
        $(element).on('click', function () {
            observable = !observable;
            
            valueAccessor()(observable);

            if (observable) {
                $(element).text('Click Here: true');
            } else {
                $(element).text('Click Here: false');
            }
        });
    }
}

function ViewModel() {
    var self = this;
    self.HasBeenClicked = ko.observable(false);
}

ko.applyBindings(new ViewModel());
div { padding: 10px; background-color: pink; margin-bottom: 10px; cursor: pointer; }
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

<div data-bind="OnClickEvent: HasBeenClicked"></div>
<span data-bind="text: 'Observable: ' + HasBeenClicked()"></span>

但是,我认为jQuery,事件处理和Knockout的这种混合是相当不确定的。您应该考虑是否遇到XY问题,以及是否使用现有的绑定处理程序无法解决您的需求。这是做类似事情的一种方法:

function ViewModel() {
    var self = this;
    self.HasBeenClicked = ko.observable(false);
    self.handleClick = function() {
      self.HasBeenClicked(!self.HasBeenClicked());
    };
}

ko.applyBindings(new ViewModel());
div { padding: 10px; background-color: pink; margin-bottom: 10px; cursor: pointer; }
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

<div data-bind="click: handleClick, text: 'Click here: ' + HasBeenClicked()"></div>
<span data-bind="text: 'Observable: ' + HasBeenClicked()"></span>

说到现有的绑定处理程序,请知道the click binding可能符合您的需求。如果没有,我建议您查看相关来源(click重定向到event绑定,请参阅this file in GitHub),为您自己的处理程序吸取灵感。