4

MathJax stops rendering the equations after any changes to the model or route. I need to reload the page to get the latex rendered right.

HTML:

<div class = "qanda" ng-model = "item">
        <ul>
              <label class="formgroup">
              <input type="radio" name = "q" >
              {{item.val}}
             </label>
             </li>
        </ul>
</div>

JS:

$scope.item = {
       "val":"Look intp \\[\\] $ \\lim\\limits_{x \\to 5} \\large\\frac{4x+b}{cx+9}$"
}

how to solve this?!

3
  • 1
    How do you update the item property? Can you put the code for that. Commented Jan 9, 2016 at 10:06
  • I don't do anything specific. I just have added the MathJax source and the script to handles inline delimiters. Commented Jan 9, 2016 at 10:52
  • Can you create a failing bin at jsbin.com. I dont know much about mathjax but it seems to be an angular problem. Commented Jan 9, 2016 at 10:54

3 Answers 3

2

You can create a simple directive that will refresh the rendering whenever source changes i.e:

var module = angular.module('test', []);

module.directive('mathJaxBind', function() {
  var refresh = function(element) {
      MathJax.Hub.Queue(["Typeset", MathJax.Hub, element]);
  };
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.mathJaxBind, function(newValue, oldValue) {
        element.text(newValue);
        refresh(element[0]);
      });
    }
  };
});
module.controller('MainCtrl', function($scope){
  $scope.equation = "When $a ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$";
});
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>

<div ng-app="test" ng-controller="MainCtrl">
  <textarea ng-model="equation"></textarea>
  <p math-jax-bind="equation"></p>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

See here in Plunker: plnkr.co/edit/463QMZdrAZSYNiAJ3N3H?p=preview, and this is very helpful: easy-copy-mathjax.xxxx7.com
Note from the future: cdn.mathjax.org is nearing its end-of-life, check mathjax.org/cdn-shutting-down for migration tips.
0

Simplest, fastest and most stable solution:

$rootScope.$watch(function(){
  MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
  return true;
});

Advantages:

  • Easy to setup, just copy this code.
  • Everything on your page is typeset.
  • It renders much faster than the other solutions. This is because it can render the page in one go. Other answers here wait for one item to finish, until they typeset the next one. That makes rendering veeeery slow if there are for example multiple mathjax-bind directives (as another answer suggests). This point is the reason I was looking for a different answer.
  • You can still easily exclude elements using the option “ignoreClass” in your mathjax settings.

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.

This answer was copied from here. All credit goes to them.

Comments

0

For the version 3 of authJax, use a directive like following:

ng-mathjax.js:

  angular.module("app").directive("mathjaxBind", function () {
  return {
    restrict: "A",
    controller: [
      "$scope",
      "$element",
      "$attrs",
      function ($scope, $element, $attrs) {
        $scope.$watch($attrs.mathjaxBind, function (texExpression) {
          $element.html(texExpression);
          MathJax.typeset([$element[0]]);
        });
      },
    ],
  };
});

mathjax-config.js:

window.MathJax = {
  tex: {
    inlineMath: [
      ["$", "$"],
      ["\\(", "\\)"],
    ],
  },
  svg: {
    fontCache: "global",
  },
};

index.html:

<html ng-app="app">
   <head>
     ...
     <script defer src="mathjax-config.js"></script>
     <script defer src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
   </head>
   <body>
     ...
      <div ng-controller="NoteController">
        <textarea id="note-content" rows="20" cols="100" ng-model="data.note"></textarea>
        <pre><span mathjax-bind="data.note"></span></pre>
      </div>
   </body>
</html>

The AngularJS controller "NoteController" is a normal controller, its code has nothing special and is omitted here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.