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

  • 1
    How do you update the item property? Can you put the code for that. – blessanm86 Jan 09 '16 at 10:06
  • I don't do anything specific. I just have added the MathJax source and the script to handles inline delimiters. –  Jan 09 '16 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. – blessanm86 Jan 09 '16 at 10:54

3 Answers3

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>
miensol
  • 39,733
  • 7
  • 116
  • 112
  • See here in Plunker: https://plnkr.co/edit/463QMZdrAZSYNiAJ3N3H?p=preview, and this is very helpful: http://easy-copy-mathjax.xxxx7.com/ – Belter Feb 15 '17 at 09:01
  • Note from the future: cdn.mathjax.org is nearing its end-of-life, check mathjax.org/cdn-shutting-down for migration tips. – Peter Krautzberger Apr 13 '17 at 07:06
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.

Community
  • 1
  • 1
Dev01
  • 13,292
  • 19
  • 70
  • 124
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.