Reputation: 2445
I have an input element which is bound to a knockout observable:
<input type="text" data-bind="value: myText, valueUpdate: 'keyup'" />
This updates the observable on each keyup. I now want to trigger additional events when the value changes.
The following does this in principle:
this.myTextTrigger = ko.computed( function () {
console.log( this.myText() );
}, this );
However, it seems somewhat clunky. It also triggers on the initial instantiation of the template, where I only want to handle changes after that. Is there an official/easier way to trigger events based on changes to observables?
Upvotes: 29
Views: 38773
Reputation: 312
If you are trying to get extra information in your binding then use allBindings.get(
nameOfOtherBinding
)
and set the nameOfOtherBinding
parameter to refer to the name of the binding in that element which is pointing to a function. Either put the function literal in the HTML or make sure you can find that function in scope of the handlers definition (like globally attached to the window
object).
http://knockoutjs.com/documentation/custom-bindings.html
JS Fiddle Example - http://jsfiddle.net/pqb4xubg/
The javascript that would set up the handler(either in init or update):
ko.bindingHandlers.generic = {
init: function(element, valueAccessor, allBindings){
var val = 'nothing';
// set your other bindings to get pulled in
var func = allBindings.get('func');
// normal check if the binding is actually a function
if(typeof func === 'function'){
// use the retrieved function
val = func(valueAccessor());
}
element.innerText = val;
}
};
var model = {a:'4', b:5};
ko.applyBindings(model);
The html that would use the handler (notice how the elements with the "fun" binding do not work):
<div data-bind="generic: a, func: function( val ){ return val + 2; }"></div>
<div data-bind="generic: a, fun: function( val ){ return val + 2; }"></div>
<div data-bind="text: a"></div>
<div data-bind="generic: b, func: function( val ){ return val + 2; }"></div>
<div data-bind="generic: b, fun: function( val ){ return val + 2; }"></div>
<div data-bind="text: b"></div>
You can also just use the init of the bind to setup standard DOM event handlers and just explicitly call those functions using something like jQuery. Thank you. Good day.
Upvotes: 3
Reputation: 15087
Use subscribe:
this.myText.subscribe(function (newText) {
console.log(newText);
});
If you want to reuse this trigger you can consider writting a custom binding.
Upvotes: 54