Question

I am using knockout.js to dynamically insert values based on an Ajax call. One of these values, content.front, is utf8 text which can contain MathJax expressions. I am trying to figure out how to get MathJax to render the expressions every time knockout.js updates the div. I can't quite get it to work, and I'm not sure why. Here's the JavaScript:

var ViewModel = function(data) {
  var self = this;
  self = ko.mapping.fromJS(data, {}, self);
  self.content.back.subscribe( function() {
      MathJax.Hub.Queue(["Typeset", MathJax.Hub,"preview-back"]);
  });
}; 

and the Hamlet:

 <div .wrap>
   <div .tab-content>
     <div .tab-pane #preview-back data-bind="text: content.back">

(The html this Hamlet renders is valid html 5...)

As it stands, knockout.js is rendering the text in the appropriate div. And when I change the text, the div changes too. And MathJax seems to be getting triggered -- the little "Typesetting 100%" popup is popping up. But the div isn't getting changed.

Was it helpful?

Solution

Okay, so I ended up making a custom binding for knockout. I'm using jquery here, too:

ko.bindingHandlers.mathjax = {
  update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    // This will be called once when the binding is first applied to an element,
    // and again whenever the associated observable changes value.
    // Update the DOM element based on the supplied values here.
    var value = valueAccessor(), allBindings = allBindingsAccessor();

    var valueUnwrapped = ko.unwrap(value);
    // the replace is an artefact of my encoding.  Maybe I will use markdown instead.
    $(element).html(valueUnwrapped.replace(/\n/g, '<br>'));
    MathJax.Hub.Queue(["Typeset",MathJax.Hub,element]);
  }
};

The ViewModel remains the same, and the html template is:

     <div data-bind="mathjax: content.back"></div>

Hopefully this will help somebody else!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top