Full-text variables of type Knockout.js

Is it possible to define (in the absence of a better term) “semi-global” variables for KO?

I would like to make the variable available for one KO template regardless of context, saving it from the actual global scope and other templates.

The goal is to have a set of helper functions that are available for only one template in any binding context (for example, inside KO foreach) without using $ parent, just like global variables are always available without special syntax. Example below:

// Template 1 - helpers.foo has been set for this Template or ViewModel <div data-bind="text:helpers.foo('Works')"></div> <div data-bind="foreach: someList"> <div data-bind="text:helpers.foo('Context is inside someList. helpers.foo is not available :( ')"></div> </div> // Template 2 - helpers.foo is not set for this Template or ViewModel <div data-bind="text:helpers.foo('Should not work')"></div> 
+4
source share
2 answers

I'm not sure yet, but I think I have found a solution. After looking at the KO documentation for the nth time, I found this: By supplying additional values ​​for child bindings .

For those of you who are: dr: I can use this binding handler to display any variable in the template in each subcontext, which is exactly what I was looking for. In other words, it becomes possible:

ViewModel

 <script> ViewModel = { Helpers: { foo: function(message) {return message;} }, someList: [ 'foo', 'bar', 'baz' ] } </script> 

HTML

 <div data-bind="text:helpers.foo('Helpers.foo can be used because we are in the root context')"></div> <div data-bind="foreach: someList"> <div data-bind="text:helpers.foo('We are in the context of someList. This will fail.')"></div> </div> <div data-bind="withProperties:{Helpers:Helpers}"> <div data-bind="foreach: someList"> <div data-bind="text:helpers.foo('Helpers.foo can now be used inside every subcontext, thanks to the withProperties custom binding')"> </div> </div> </div> 

In my case, custom wrapper bindings can be applied automatically when loading for each template, so this seems like a great solution for me!

I will try this method and publish the following information if it happens that I missed something. This question will be left open for a short time, because I can not accept my own answer so quickly. Meanwhile, do not hesitate to publish your decisions, I am sure that there are several more approaches to solving this issue.

+3
source

You must define a new custom binding that retrieves values ​​from your helper. Just for a simple example:

 // your "semi-globally" accessible helpers var helpers = { foo: function(text){ return "<b>" + text + "</b>"; }, boo: function(text){ return "<u>" + text + "</u>"; } }; // custom binding ko.bindingHandlers.helpers = { init: function(element, valueAccessor) { var opts = valueAccessor(); element.innerHTML = helpers[opts.name].apply(element, opts.args); } }; // two different primitive ViewModels without any ref to helpers function VM_1 () { this.name = "vm-1"; } function VM_2 () { this.name = "vm-2"; } // binding models ko.applyBindings(new VM_1, document.getElementById("vm-1")); ko.applyBindings(new VM_2, document.getElementById("vm-2")); 

HTML:

 <div id="vm-1"> <span data-bind="text: name"></span> <span data-bind="helpers: { name: 'foo', args: ['Works!'] }"></span> </div> <div id="vm-2"> <span data-bind="text: name"></span> <span data-bind="helpers: { name: 'foo', args: ['Works perfectly!'] }"></span> </div> 

http://jsfiddle.net/ostgals/GfBJ9/1/

+2
source

All Articles