Getting MathJax to update after changes to AngularJS model

后端 未结 10 621
甜味超标
甜味超标 2020-11-30 02:02

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

相关标签:
10条回答
  • 2020-11-30 02:37

    You can try with my modifications http://jsfiddle.net/bmma8/4/ modify input or click on button will update your expression.

    js:

    MathJax.Hub.Config({
        extensions: ["tex2jax.js"],
        jax: ["input/TeX","output/HTML-CSS"],
        tex2jax: {inlineMath: [["$","$"],["\\(","\\)"]]}
    });
    
    var myApp = angular.module('myApp',[]);
    
    
    function MyCtrl($scope, $log) {
    
        var QUEUE = MathJax.Hub.queue;  // shorthand for the queue
    
        $scope.Update = function() {
            QUEUE.Push(["Text",MathJax.Hub.getAllJax("MathOutput")[0],"\\displaystyle{"+ $scope.Expression+"}"]);
            //$scope.Expression = 'Updated Expression: \\( \\frac{9}{4} \\div \\frac{1}{6} \\)';
            //MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
        }
        $scope.Expression = 'Original Expression: \\( \\frac{5}{4} \\div \\fra
    

    and html:

     <div ng-controller="MyCtrl">
             <button ng-click="Update()">Update</button>
    
             <input ng-model="Expression" ng-change="Update()">
             <div id="MathOutput">
             You typed: ${}$
             </div>
     </div>
    

    Alexandre

    0 讨论(0)
  • 2020-11-30 02:40

    I Build a directive for this....

    FIDDLE: http://jsfiddle.net/8YkUS/1/

    HTML

    p data-math-exp data-value="math">

    JAVASCRIPT

     appFlipped.directive("mathExp", function () {
        return {
            scope: {
                value: "="
            },
            link: function (scope, el) {
    
                var domEl = el[0];
                scope.$watch("value", function (newValue) {
    
                    //nothing to do here
                    if (newValue == null || window.MathJax == null)return;
    
                    //update the dom with the new value and pass the hub for styling the equation
                    domEl.innerHTML = '`' + newValue + '`';
                    MathJax.Hub.Queue(["Typeset", MathJax.Hub, domEl]);
                });
            }
        }
    });
    
    0 讨论(0)
  • 2020-11-30 02:41

    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.

    0 讨论(0)
  • 2020-11-30 02:44

    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 called mathjax-bind.

    If expression is a variable containing math code, then instead of \( {{expression}} \) you can write:

    <span mathjax-bind="expression"></span>
    

    and everything will be typeset and updated at the appropriate times.

    The supporting code for the directive follows:

    myApp.directive("mathjaxBind", function() {
        return {
            restrict: "A",
            controller: ["$scope", "$element", "$attrs",
                    function($scope, $element, $attrs) {
                $scope.$watch($attrs.mathjaxBind, function(texExpression) {
                    var texScript = angular.element("<script type='math/tex'>")
                        .html(texExpression ? texExpression :  "");
                    $element.html("");
                    $element.append(texScript);
                    MathJax.Hub.Queue(["Reprocess", MathJax.Hub, $element[0]]);
                });
            }]
        };
    });
    
    0 讨论(0)
提交回复
热议问题