这里有点晚了。我实际上对 RP 的回答并不满意,因为它破坏了 Knockout 的声明性。具体来说,如果您使用 valueWithInit 来定义您的属性,则不能在较早的绑定中使用它。这是他的 jsfiddle 的一个分支来演示。
您以相同的方式使用它,但它仍然是文档范围内的声明性:
<input data-bind="valueWithInit: firstName" value="Joe" />
扩展这个想法,您还可以使用它来分离初始化和绑定:
<input data-bind="initValue: lastName, value: lastName" value="Smith" />
这有点多余,但当您使用插件而不是内置绑定时会变得很有用:
<input data-bind="initValue: lastName, myPlugin: lastName" value="Smith" />
再扩展一点,我还需要一种初始化复选框的方法:
<input type="checkbox" data-bind="checkedWithInit: isEmployed" checked />
这里是处理程序:
ko.bindingHandlers.initValue = {
init: function(element, valueAccessor) {
var value = valueAccessor();
if (!ko.isWriteableObservable(value)) {
throw new Error('Knockout "initValue" binding expects an observable.');
}
value(element.value);
}
};
ko.bindingHandlers.initChecked = {
init: function(element, valueAccessor) {
var value = valueAccessor();
if (!ko.isWriteableObservable(value)) {
throw new Error('Knockout "initChecked" binding expects an observable.');
}
value(element.checked);
}
};
ko.bindingHandlers.valueWithInit = {
init: function(element, valueAccessor, allBindings, data, context) {
ko.applyBindingsToNode(element, { initValue: valueAccessor() }, context);
ko.applyBindingsToNode(element, { value: valueAccessor() }, context);
}
};
ko.bindingHandlers.checkedWithInit = {
init: function(element, valueAccessor, allBindings, data, context) {
ko.applyBindingsToNode(element, { initChecked: valueAccessor() }, context);
ko.applyBindingsToNode(element, { checked: valueAccessor() }, context);
}
};
注意valueWithInit
只是initValue
在引擎盖下使用。
在 jsfiddle 上查看它的实际效果。