0

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)?

Brian M. Hunt
  • 81,008
  • 74
  • 230
  • 343
  • An interesting (but probably not feasible) approach could also be to define `getter` and `setter` methods in your viewmodel's observables. Like in this example by Ryan Niemeyer: https://jsfiddle.net/rniemeyer/mrCSH/ I can imagine you want to find a solution in the templating part though, instead of changing the way you define your viewmodels... – user3297291 Jun 09 '16 at 07:51
  • @user3297291 Yes, that's definitely an option, too, which I should've mentioned. One could use Steve Sanderson's [Knockout-es5](https://github.com/SteveSanderson/knockout-es5) for this. That said, Knockout-ES5 is not always suitable. – Brian M. Hunt Jun 09 '16 at 12:12
  • Incidentally, I find LinkedIn's `dust.js` to be quite forgiving in many of the right ways. :) – Brian M. Hunt Jun 09 '16 at 14:25

1 Answers1

0

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).

Brian M. Hunt
  • 81,008
  • 74
  • 230
  • 343