It looks like you just need to wait for the DOM to settle down before MathJax can process it. A simple setTimeout
call seems to fix the issue:
$http({method: 'GET', url: 'data.json'})
.success(function(data) {
$scope.data = data;
setTimeout(function() {
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
});
});
See http://plnkr.co/edit/xIVvUHntVZ7lftGz9cDn?p=preview for an example.
You mentioned using a directive; you could use one to abstract away the need to call the MathJax function manually at all.
In this example, I've created a directive called math
that automatically lays out whatever's passed in with MathJax:
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/");//Was defaulting to route 1. No more
$stateProvider.state('route1', {
url: "/route1",
templateUrl: "route1.html",
controller: function($scope, $http, $timeout){
$http({method: 'GET', url: 'data.json'})
.success(function(data) {
$scope.data = data;
});
}
});
});
myapp.directive('math', function() {
return {
restrict: 'EA',
scope: {
math: '@'
},
link: function(scope, elem, attrs) {
scope.$watch('math', function(value) {
if (!value) return;
elem.html(value);
MathJax.Hub.Queue(["Typeset", MathJax.Hub, elem[0]]);
});
}
};
});
<hr>
<h3>Route 1's data</h3>
<p>
<strong>Name:</strong>
{{data.name}}
</p>
<p>
<strong>Equation:</strong>
<span math="{{data.equation}}"></span>
</p>
See http://plnkr.co/edit/c9NBXXd9kF7Jne6saS3i?p=preview for a demonstration.
Going this route, absolutely anything passed to the math
directive will be automatically rendered with MathJax whenever it changes. See this demo for an example that lets you edit the equation: http://plnkr.co/edit/dJSEGtBKSrKLjiwuLsl5?p=preview