Mik*_*sen 36 javascript jquery knockout.js
好吧,我一直试图解开这个烂摊子几个小时,现在已经无处可去,类似于追逐尾巴的狗.这是情况.
我正在使用Knockout.js作为我的UI,它本身很好用.但是,我正在尝试使用一些第三方代码,使下拉列表和复选框看起来很漂亮.实际上我甚至不确定这是第三方库还是我们设计师写的东西.此代码隐藏了真实的复选框,并将其替换为<span />
通过CSS模仿复选框的伪造.该click
跨度的事件触发change
的实际复选框的事件:
// this code updates the fake UI
this._changeEvent = function() {
self.isChecked = self.$input.is(':checked');
self._updateHTML(false, true);
jQuery(self).trigger('change');
};
// when the user clicks the fake checkbox, we trigger change on the real checkbox
this.$fake.on('click', function(e) {
e.preventDefault();
self.$input.click().trigger('change');
});
// Bind _changeEvent to the real checkbox
this.$input.change(this._changeEvent);
Run Code Online (Sandbox Code Playgroud)
这实际上适用于Knockout.js,因为Knockout将侦听该事件处理程序.换句话说,当用户单击假复选框时,绑定的Knockout模型会更新.然而,有什么不工作是更新模型.如果我打电话:
model.SomeValue(!curValue); // SomeValue is bound to a checkbox, flip its value
Run Code Online (Sandbox Code Playgroud)
模型会更新,但虚假的UI不会更新.我已经将这个问题追溯到下面的代码ko.bindingHandlers.checked.update
:
// When bound to anything other value (not an array), the checkbox being checked represents the value being trueish
element.checked = value;
Run Code Online (Sandbox Code Playgroud)
基本上,element.checked
属性已设置,但不会触发任何事件.因此,_changeEvent
永远不会调用该函数.所以,我已经实现了我自己的ko.bindingHandlers.checked.update
功能,它是内置功能的副本.从理论上讲,这就是我应该做的所有事情:
ko.bindingHandlers.checked.update = function (element, valueAccessor)
{
var value = ko.utils.unwrapObservable(valueAccessor());
if (element.type == "checkbox")
{
if (value instanceof Array)
{
// When bound to an array, the checkbox being checked represents its value being present in that array
element.checked = ko.utils.arrayIndexOf(value, element.value) >= 0;
}
else
{
// When bound to anything other value (not an array), the checkbox being checked represents the value being trueish
//element.checked = value;
$(element).prop('checked', value).trigger('change'); // <--- this should work!
}
}
else if (element.type == "radio")
{
element.checked = (element.value == value);
}
};
Run Code Online (Sandbox Code Playgroud)
而不是设置element.checked
,而是调用.prop('checked', value)
并触发更改事件.但是,这不起作用.这是我目前所知道的:
$(element).prop('checked', value).trigger('change');
效果非常好.所以,knockout.js正在调整事件的一些方式.它解除了那个事件处理程序吗?$(element)
的是同样的事情this.$input
在假复选框绑定代码.我可以在这个元素上设置其他expando属性,然后它们就会显示出来.change
自己的内部处理程序替换了事件处理程序,并删除了现有的绑定.我还没有办法确认这一点.我的问题:主要是,我正在寻找解决这个问题的方法.Knockout.js是否删除change
了在应用模型之前存在的现有事件?调试此代码并弄清楚究竟发生了什么的下一步是什么?
Try triggering and listening also for a custom event:
element.checked = value;
element.dispatchEvent(new Event("forcedChange"));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2872 次 |
最近记录: |