问题描述
我无法为此找到解决方案.
I have not been able to find a solution for this.
我正在尝试为html元素 div 标记上的click事件创建自定义bindingHandler.
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>
此bindingHandler会执行预期的操作,如果单击 div ,文本将更改.但是,可观察者说 false .
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());
如何设置可观察的 HasBeenClicked ,以便在每次点击(如文本)时在是/否之间切换?
How do I set the observable HasBeenClicked to switch between true/false on every click, like the text?
推荐答案
我第二次@nemesv对快速修复的评论以及您的绑定看起来有些奇怪的事实.我将其扩展为一个答案,因为我需要房间.
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.
首先,快速修复:
- 我认为对于您要编写的绑定类型,更适合在
init
部分内部进行工作; - 您需要写回
valueAccessor
来更改可观察对象的值(我在下面显示了一个快速且肮脏的演示);
- 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);
这是一个可行的示例:
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问题,以及是否无法使用现有的绑定处理程序解决要求.这是做类似事情的一种方法:
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>
说到现有的绑定处理程序,请知道 click
绑定满足您的需求.如果没有,我建议您查看相关源(click
重定向到event
绑定,请参见此文件在GitHub中),以为您自己的处理程序吸引灵感.
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.
这篇关于自定义bindingHandler的返回值/可观察的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!