目前我正在使用knockout 2.1.0,其中以下的datepicker绑定完美地处理不可观察的值。当我更新了淘汰赛3.0时它无法正常工作
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindingsAccessor) {
// Get the options from the binding.
var options = allBindingsAccessor().datepickerOptions || {};
$(element)
.datepicker(options)
.bind("change", function() {
ko.bindingHandlers.datepicker.updateValue(element, valueAccessor, allBindingsAccessor);
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).datepicker("destroy");
});
},
update: function(element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
// If the date is coming from a Microsoft webservice.
if (typeof value === "string" && value.indexOf('/Date(') === 0) {
value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
}
var currentDate = $(element).datepicker("getDate");
// Check if the date has changed.
if (value && value - currentDate !== 0) {
$(element).datepicker("setDate", value);
}
},
updateValue: function(element, valueAccessor, allBindingsAccessor) {
var observable = valueAccessor(),
dateValue = $(element).datepicker("getDate");
// Two-way-binding means a writeable observable.
if (ko.isWriteableObservable(observable)) {
observable(dateValue);
return;
}
if (allBindingsAccessor()._ko_property_writers) {
allBindingsAccessor()._ko_property_writers.datepicker(dateValue);
}
}
};
当我调试代码时,我知道allBindingsAccessor()._ko_property_writers
未定义。因此,我无法更新不可观察的值。
有人可以建议我在3.0版本中使用上述代码的解决方案
通过使用下面的示例,我修改了我的自定义绑定,它工作得很好。请找到更新的小提琴
答案 0 :(得分:1)
问题是_ko_property_writers
是一个私有实现细节(这就是为什么名称是_
的前缀)。如果您阅读line 188-195 in the source code for expression rewriting in knockout,则会发现其中包含以下内容:
使绑定明确地将自己声明为"双向"从长远来看并不理想(如果所有绑定都可以使用官方的属性编写器API而不需要声明它们可能会更好)。但是,由于这不是,而且从未如此,公共API(_ko_property_writers从未记录过),它在短期内可以作为内部实现细节。
对于那些在自定义绑定中依赖_ko_property_writers的开发人员,我们将_twoWayBindings作为未记录的功能公开,这使得升级到KO 3.0相对容易。但是,这仍然不是官方的公共API,如果我们创建一个真正的公共属性编写器API,我们保留随时删除它的权利。
因此,似乎仍然没有公共API不会更改为未来版本,但您应该能够使用_twoWayBindings
,直到决定并提供此类API。
更新2014-04-15 - 添加设置双向绑定标志的示例
_twoWayBindings
设置(可能会在任何未来版本的淘汰赛中消失,因为它不是真正的公共API,不幸的是)是您在创建bindingHandler
时可以设置的标记告诉knockout为您的_ko_property_writers
创建bindingHandler
条目。设置此标志的方式与创建新bindingHandler的方式类似:
ko.expressionRewriting._twoWayBindings['simpleTwoWayBinding'] = true;
绑定的完整示例,它将对不可观察的属性进行双向绑定:
ko.expressionRewriting._twoWayBindings['simpleTwoWayBinding'] = true;
ko.bindingHandlers['simpleTwoWayBinding'] = {
init: function(element, valueAccessor, allBindings, viewModel){
element.value = valueAccessor();
var valueSetter = allBindings.get('_ko_property_writers').simpleTwoWayBinding;
element.addEventListener('change', function(){
valueSetter(element.value);
});
}
};
我有一个可以在http://jsfiddle.net/p8ugz/
找到的工作样本但是,请注意上述代码不适用于可观察属性。要支持两者,您需要检查它是否绑定到一个可观察对象,并且在这种情况下只使用普通的可观察对象,如果它不是可观察的,则使用_ko_property_writers
。