To reference your function from your knockout templates, it needs to be attached to a ViewModel. In the simple case above, you can just attach it to demoViewModel and reference it in your template directly:
function myFunction(text){
return text + '--';
}
function demoViewModel() {
var self = this;
self.names = ['a', 'b', 'c'];
self.myFunction = myFunction;
return self;
}
ko.applyBindings(new demoViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: names">
<li data-bind="text: myFunction($data)"></li>
</ul>
This isn't really a "global" function, it's just a standard viewModel property and if you ended up with nested binding contexts you'd have to do $parents[n].myFunction or, if you've attached it to your root viewModel, you could do $root.myFunction.
Another way to handle this is to add the function to the binding context directly. This allows it to be referenced regardless of what the current viewModel is.
The "as" option on "foreach" binding handlers and template binding handlers is one way of adding things to the binding context; but I use a "let" bindingHandler for this purpose, the let bindingHandler isn't an official part of KO, but is often recommended by Michael Best, one of the core contributors.
function myFunction(text){
return text + '--';
}
function demoViewModel() {
var self = this;
self.names = ['a', 'b', 'c'];
self.myFunction = myFunction;
return self;
}
//Let binding Handler
ko.bindingHandlers['let'] = {
'init': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// Make a modified binding context, with extra properties, and apply it to descendant elements
var innerContext = bindingContext.extend(valueAccessor());
ko.applyBindingsToDescendants(innerContext, element);
return { controlsDescendantBindings: true };
}
};
ko.virtualElements.allowedBindings['let'] = true;
ko.applyBindings(new demoViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!-- ko let: {
myFunction: myFunction
} -->
<ul data-bind="foreach: {
data: names,
at: 'name'
}">
<li data-bind="text: myFunction($data)"></li>
</ul>
<!-- /ko -->
In the above example, you can reference myFunction anywhere within the let binding, regardless of how many levels deep of viewModels you are.
var self = thison your demoVM; you're actually using the global window.self object as your VM right now. - Retsamwindow.myFunctionshould work, right? jsfiddle.net/2prmfwyx Have a look at how knockout'sbindingContextworks and its internal use of thewithkeyword viawith($data || {})- user3297291