A custom bindingHandler's return value/observable

自闭症网瘾萝莉.ら 提交于 2019-12-13 07:45:59

问题


I have not been able to find a solution for this.

I'm trying to create a custom bindingHandler for a click event on an html element div tag.

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

This bindingHandler does what it is suppose to, if you click on the div the text will change. However, the observable says if 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());

How do I set the observable HasBeenClicked to switch between true/false on every click, like the text?


回答1:


I second @nemesv's comment on the quick fix as well as the fact that your binding looks a bit strange. I'll expand it to an answer because I need the room.

First up, the quick fix:

  • I think for the type of binding you're writing it's more appropriate to do your work inside the init part;
  • You need to write back to the valueAccessor to change the observable's value (I show a quick and dirty demo below);

Here's a working example:

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>

However, I think this kind of mix of jQuery, event handling, and Knockout is rather iffy. You should consider whether you're suffering from an XY-problem, and whether you can't solve your requirement using existing binding handlers. Here's one way to do something similar:

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>

Speaking of existing binding handlers, know that there's the click binding which may suit your needs. If it doesn't, I'd recommend looking at the relevant source (click redirects to the event binding, see this file in GitHub), to draw inspiration for your own handler.



来源:https://stackoverflow.com/questions/30571075/a-custom-bindinghandlers-return-value-observable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!