I am trying to use AngularJS two-way binding text which includes Latex style equations. I would like to call MathJax to format the equations, but I'm not sure of the best way to ensure that MathJax is called after AngularJS finishes changing the model. I think I need a callback. Here is my JavaScript:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.Update = function() {
$scope.Expression = 'Evaluate: \\( \\frac{9}{4} \\div \\frac{1}{6} \\)';
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
}
$scope.Expression = 'Evaluate: \\( \\frac{5}{4} \\div \\frac{1}{6} \\)';
}
And here is my HTML:
<div ng-controller="MyCtrl">
<button ng-click="Update()">Update</button>
{{Expression}}
</div>
Fiddle is here: http://jsfiddle.net/LukasHalim/UVjTD/1/. You'll notice that on the fiddle the original expression isn't removed even after you click the update button twice - seems like a bug or conflict.
Here's a directive that lets you use double curly markup inside the expression (and doesn't require setting an expression variable on the scope). It's based on this blog post, except I only support MathJax, and I save the compiled DOM, so that it updates on changes to scope variables.
As Alex Osborn said, it's best to separate non-math from math.
Usage:
In a snippet:
You can try with my modifications http://jsfiddle.net/bmma8/4/ modify input or click on button will update your expression.
js:
and html:
Alexandre
Simplest, fastest and most stable solution:
Advantages:
mathjax-bind
directives (as another answer suggests). This point is the reason I was looking for a different answer.Benchmarking: 100
mathjax-bind
directives took 63 seconds, while with this method it took 1.5 second to render the page. I know that this function will be executed a lot since it's called on every digest cycle, however, it doesn't noticeably slow down the page.I actually thought of another solution. When you render some angular and math you do this:
ANGULAR CONTROLLER
HTML
Formated Math Jax result
Multiplication = 5 * 2 = 10
The key is to include the dollar signs inside the brackets as text. When Angular renders them, the dollar signs will appear as plain text, but when the Math Jax format comes into action it will recognize the dollar signs and do the magic.
I fiddled a bit more on Roney's solution. The display math should be displayed in display mode; with
I added an attribute to the generated span to indicate that.
Fiddle is here http://jsfiddle.net/repa/aheujhfq/8/
Having wasted many days (and maybe weeks) fighting MathJax, I'm all too familiar with its various quirks with updating math expressions on the fly. I'm brand new to Angular but this gave me a good chance to dive in and I ended up with a solution which solves my problems -- hopefully it'll solve yours as well.
Live demo: jsfiddle
Instead of using the plain interpolation that Angular provides, I created a new directive based on
ng-bind
calledmathjax-bind
.If
expression
is a variable containing math code, then instead of\( {{expression}} \)
you can write:and everything will be typeset and updated at the appropriate times.
The supporting code for the directive follows: