实现此目的的一种方法是使用事件。
您可以向自定义绑定传递事件名称并让它订阅该事件。
由于我使用的是 Durandal,我通常会使用内置事件系统,但 jsFiddle 只有 KnockoutJS 可用,因此以下示例使用了一个小型PubSub 库。
这是示例代码,而不是任何将投入生产的东西。
jsFiddle
//PubSub//
(function(a,c,b){if(typeof module!=="undefined"){module.exports=b(a,c)}else{if(typeof define==="function"&&typeof define.amd==="object"){define(b)}else{c[a]=b(a,c)}}})("radio",this,function(b,c){function a(d){a.$.channel(d);return a.$}a.$={version:"0.2",channelName:"",channels:[],broadcast:function(){var f,j=this.channels[this.channelName],d=j.length,g,h,e;for(f=0;f<d;f++){g=j[f];if((typeof(g)==="object")&&(g.length)){h=g[0];e=g[1]||c}h.apply(e,arguments)}return this},channel:function(d){var e=this.channels;if(!e[d]){e[d]=[]}this.channelName=d;return this},subscribe:function(){var f=arguments,j=this.channels[this.channelName],g,e=f.length,h,d=[];for(g=0;g<e;g++){d=f[g];h=(typeof(d)==="function")?[d]:d;if((typeof(h)==="object")&&(h.length)){j.push(h)}}return this},unsubscribe:function(){var g=arguments,k,h,n=this.channels[this.channelName],f=g.length,e=n.length,m=0,d;for(k=0;k<f;k++){m=0;e=n.length;for(h=0;h<e;h++){d=h-m;if(n[d][0]===g[k]){n.splice(d,1);m++}}}return this}};return a});
//PubSub//
ko.bindingHandlers.customBinding = {
_textBoxes: {},
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var _valueAccessor = valueAccessor();
var textBox = document.createElement("input");
textBox.type = "text";
element.appendChild(textBox);
ko.bindingHandlers.customBinding._textBoxes[element.id] = textBox;
if(_valueAccessor.clearEventName) {
radio(_valueAccessor.clearEventName).subscribe(function() {
_valueAccessor.text("");
});
}
if(_valueAccessor.text) {
textBox.onchange=function() { _valueAccessor.text(textBox.value); };
}
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var _valueAccessor = valueAccessor();
if(_valueAccessor.text) {
ko.bindingHandlers.customBinding._textBoxes[element.id].value = _valueAccessor.text();
}
}
};
var viewModel = {
text: ko.observable("Inital value."),
doClear: function() {
radio('clear').broadcast();
},
doReset: function() {
viewModel.text("Reset value.");
}
};
ko.applyBindings(viewModel);