Reputation: 3852
From knockout documentation :
ko.bindingHandlers.<name>.preprocess(value, name, addBindingCallback)
Parameters:
value: ...
name: ...
addBinding: a callback function you can optionally use to insert another binding on the current element. This requires two parameters, name and value. For example, inside your preprocess function, calladdBinding('visible', 'acceptsTerms()');
to make Knockout behave as if the element had avisible: acceptsTerms()
binding on it.
For example we can have bindings like :
ko.bindingHandlers.live = {
preprocess: function (str, name, addBindingCallback) {
addBindingCallback('value', str);
addBindingCallback('valueUpdate', "'afterkeydown'")
}
};
// Or
ko.bindingHandlers.log = {
preprocess: function (str, name, addBindingCallback) {
addBindingCallback('click', "function(){console.log('test');}");
}
};
My Question:
Is it possible to pass a variable within the scope of preporcess
method to the newly added bindings ?
ko.bindingHandlers.log = {
preprocess: function (str, name, addBindingCallback) {
// an object which is not in my viewmodel and context
var $scoped_obj = get_from_some_external_service(str);
// i want to pass `$scoped_obj` to the newly added click binding
addBindingCallback('click', "function(){console.log($scoped_obj);}");
}
};
Is that possible ? and How ?
Upvotes: 2
Views: 613
Reputation: 15053
The way you're trying it now, you can't, because the click handler is evaluated by a Function
, which accepts a string as the function body. The scope is lost at that point.
What you could do is create a static function which you call inside the click handler:
ko.bindingHandlers.log = {
functions: [],
preprocess: function (str, name, addBindingCallback) {
var fnIndex = ko.bindingHandlers.log.functions.length;
var $scoped_obj = {a: 'b'};
ko.bindingHandlers.log.functions.push(function() {
console.log($scoped_obj);
});
addBindingCallback('click', "ko.bindingHandlers.log.functions["+fnIndex+"]");
}
};
See http://jsfiddle.net/fpoeeb7L/
Alternatively you could use ko.toJSON
to create the variable inside the click handler:
ko.bindingHandlers.log = {
preprocess: function (str, name, addBindingCallback) {
var $scoped_obj = {a: 'b'};
addBindingCallback('click', "function() { var $scoped_obj = " + ko.toJSON($scoped_obj) + "; console.log($scoped_obj); }");
}
};
See http://jsfiddle.net/5e5jbuum/
But this won't work if $scoped_obj
contains functions.
Upvotes: 4
Reputation: 39045
You can use a self-executing function to create a closure for the scoped variable. Use the closure to create the scoped variable and the function that uses it, and return the function, like so:
preprocess: (function() {
var $scoped_obj = get_from_some_external_service(str);
var fn = function(str, name, addBindingCallback) {
// can use the scoped variable
};
return fn;
})(); // self-execution
However, take into account Jeff Mercado's comment to your question.
Upvotes: 1