The problem is that _ko_property_writers
is a private implementation detail (which is why the name is prefix with _
). If you read line 188-195 in the source code for expression rewriting in knockout you'll see that it states the following:
Making bindings explicitly declare themselves as "two way" isn't ideal in the long term (it would be better if all bindings could use an official 'property writer' API without needing to declare that they might). However, since this is not, and has never been, a public API (_ko_property_writers was never documented), it's acceptable as an internal implementation detail in the short term.
For those developers who rely on _ko_property_writers in their custom bindings, we expose _twoWayBindings as an undocumented feature that makes it relatively easy to upgrade to KO 3.0. However, this is still not an official public API, and we reserve the right to remove it at any time if we create a real public property writers API.
So it would seem like there is still not a public API which won't change to future versions, but you should be able to use _twoWayBindings
until such an API is decided and provided.
UPDATED 2014-04-15 - Adding a sample of setting the two way binding flag
The _twoWayBindings
setting (which might disappear in any future version of knockout, since it's not really a public API, unfortunately) is a flag you can set when you create your bindingHandler
to tell knockout to create a _ko_property_writers
entry for your bindingHandler
. The way you set this flag is similar to how you create a new bindingHandler:
ko.expressionRewriting._twoWayBindings['simpleTwoWayBinding'] = true;
A complete example of a binding which would do two way binding to non-observable properties:
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);
});
}
};
I have a working sample which you can find at http://jsfiddle.net/p8ugz/
However, do be aware that the above code will not work with observable properties. To support both, you need to check if it's bound to an observable and just work with ordinary observables in that case and with the _ko_property_writers
if it's not an observable.