I am trying to use a Knockout-style view-model with a mustache-like language.
So the view model looks something like this:
var viewModel = {
aValue: ko.observable("boot")
}
The rather common problem with mustache-like languages is that they do not unwrap the models. So one gets e.g.
mustache_lib.render("{{ aValue }}", viewModel)
=> "function (initialvalue) { function observable() { ..."
That's what happens with Nunjucks, among others (with their respective render
function).
One could use a filter with Nunjucks, so the following works as expected:
nunjucks.renderString("{{ aValue | unwrap }}", viewModel)
=> "boot"
Where unwrap
is a filter, being ko.unwrap
. However I am not a fan of the syntax, and I was wondering if there were a better option. I perused Nunjucks code and it did not seem possible to automatically unwrap every variable looked up in a context.
Handlebars.js has a preferable syntax (in my eyes), e.g.
Handlebars.compile("{{ unwrap aValue }}")(viewModel)
=> "boot"
Unfortunately if you forget the unwrap
, then aValue
will be treated as a helper and called with an undesirable value, something like { data: Object, hash: '', name: '...' }
. Obviously one prefers not to have their templating language do this. Similar to Nunjucks, Handlebars does not have a way to modify the context lookups to automatically call ko.unwrap
.
Interestingly, Mustache.js will call any variable that is a function
(including, of course, observables). However it lacks a number of features in other libraries.
Has anyone had any experience with using Mustache-like libraries with Knockout and worked through the relationship (including which mustache libraries are most suitable)?
FWIW, I ended up using dust.js, and making ko.subscribable's thenable
by adding a then
function to ko.subscribable.fn
(with then
resolution being prioritized in the next release of dust.js).