我正在尝试学习Knockout,同时构建一个相当复杂的动态表单,使用jQuery插件Uniform JS进行样式设置。由于Knockout动态地动态构建表单的一部分,我需要确保Uniform JS保持并动态生成动态生成的表单元素。
经过一番搜索后,我发现Mikhail Temkine的一篇名为“Knockout JS knockouts”的博客文章解释了如何编写自定义Knockout绑定以解决Uniform样式复选框的问题。自定义绑定如下所示:
ko.bindingHandlers.checkedUniform = {
init: function (element, valueAccessor) {
ko.bindingHandlers.checked.init(element, valueAccessor);
},
update: function (element, valueAccessor) {
ko.bindingHandlers.checked.update(element, valueAccessor);
$.uniform.update($(element));
}
};
简化的HTML看起来像这样:
<ul data-bind="foreach: items">
<li data-bind="text: name, click: $root.editItem, css: {bold: bolded()}"></li>
</ul>
<div data-bind="with: selectedItem">
Edit list item: <input data-bind="value: name" />
Make it bold: <input type="checkbox" data-bind="checkedUniform: bolded />
</div>
自定义绑定显然使用uniform.update()
方法,该方法应该刷新样式化复选框的状态。不幸的是它不起作用。复选框根据所选的统一设计模板进行样式设置,但只要重新渲染Knockout模板(在这种情况下selectedItem
更改时),指示复选框是否勾选的指示符就会丢失。复选框仍然有效,您可以点击它们切换状态,只是它们总是显示为未选中状态。
我创建了一个简单的jsFiddle来演示问题:
答案 0 :(得分:2)
您的样式会丢失,因为在使用with
绑定时,它会在其值更改时替换下面的DOM。因此,您的初始$('input[type="checkbox"]').uniform();
将不会应用于新创建的复选框。
要解决此问题而不是通常应用uniform
插件,请将初始化逻辑移动到checkedUniform
初始化函数中(即使元素刚刚由KO创建,它也会在绑定应用于元素后运行一次):
ko.bindingHandlers.checkedUniform = {
init: function (element, valueAccessor) {
ko.bindingHandlers.checked.init(element, valueAccessor);
$(element).uniform();
},
update: function (element, valueAccessor) {
ko.bindingHandlers.checked.update(element, valueAccessor);
$.uniform.update($(element));
}
};
演示JSFiddle。