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