在更改AngularJS模型后更新MathJax

Luk*_*lim 26 mathjax angularjs

我正在尝试使用包含Latex风格方程的AngularJS双向绑定文本.我想调用MathJax来格式化方程式,但我不确定在AngularJS完成模型更改后确保调用MathJax的最佳方法.我想我需要一个回调.这是我的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} \\)';
Run Code Online (Sandbox Code Playgroud)

}

这是我的HTML:

<div ng-controller="MyCtrl">
    <button ng-click="Update()">Update</button>
  {{Expression}}
</div>
Run Code Online (Sandbox Code Playgroud)

小提琴在这里:http://jsfiddle.net/LukasHalim/UVjTD/1/.您会注意到,即使您单击两次更新按钮,原始表达式也不会被删除 - 看起来像是一个错误或冲突.

Sop*_*ert 36

浪费了许多天(也许是几周)与MathJax作斗争,我对其动态更新数学表达式的各种怪癖都非常熟悉.我是Angular的新手,但这给了我一个很好的机会潜入,我最终得到了一个解决我的问题的解决方案 - 希望它也能解决你的问题.

现场演示:http://jsfiddle.net/spicyj/YpqVp/


我没有使用Angular提供的普通插值,而是创建了一个基于ng-bind被调用的新指令mathjax-bind.

如果expression是包含数学代码的变量,那么\( {{expression}} \)您可以编写:

<span mathjax-bind="expression"></span>
Run Code Online (Sandbox Code Playgroud)

一切都将在适当的时候排版和更新.

该指令的支持代码如下:

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]]);
            });
        }]
    };
});
Run Code Online (Sandbox Code Playgroud)

  • 如果您更喜欢使用`\(... \)`分隔符而不是使用单独的标记专门插入数学,请不要绝望!如果你改变watch回调使用`$ element.text(value == undefined?"":value);`并在`$ watch`处理程序中运行`Typeset`而不是`Reprocess`,那么你将会让它排版包含任意数量的数学表达式的整个文本. (3认同)
  • 如果我的"表达式"有一些html标签,我怎么能这样做?我如何使用ng-bind-html和mathjax绑定? (3认同)

小智 13

最简单,最快速,最稳定的解决方案:

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

好处:

  • 易于设置,只需复制此代码即可.
  • 页面上的所有内容都是排版的.
  • 它的渲染速度比其他解决方案快得多.这是因为它可以一次渲染页面.其他答案在这里等待一个项目完成,直到他们排版下一个.如果有多个mathjax-bind指令(如另一个答案所示),这会使渲染速度变慢.这一点是我寻找不同答案的原因.
  • 您仍然可以使用mathjax设置中的"ignoreClass"选项轻松排除元素.

基准测试:100个mathjax-bind指令耗时63秒,而使用此方法渲染页面需要1.5秒.我知道这个函数会被执行很多,因为它在每个摘要周期都被调用,但是,它并没有明显减慢页面的速度.


Ron*_*and 7

我创造了一个简单的小提琴,扩展了Ben Alpert的答案.这是小提琴插件.

特别是如果文本只有一部分要由Mathjax转换,您可以使用它.对于内联mathjax,您必须用$围绕文本,对于块显示,您必须用$$围绕块.(如果创建相应的正则表达式,可以使用任何您喜欢的格式)

app.js

MathJax.Hub.Config({
    skipStartupTypeset: true,
    messageStyle: "none",
    "HTML-CSS": {
        showMathMenu: false
    }
});
MathJax.Hub.Configured();
var myApp = angular.module("myApp", []);
myApp.directive("mathjaxBind", function() {
    return {
        restrict: "A",
        scope:{
            text: "@mathjaxBind"
        },
        controller: ["$scope", "$element", "$attrs", function($scope, $element, $attrs) {
            $scope.$watch('text', function(value) {
                var $script = angular.element("<script type='math/tex'>")
                    .html(value == undefined ? "" : value);
                $element.html("");
                $element.append($script);
                MathJax.Hub.Queue(["Reprocess", MathJax.Hub, $element[0]]);
            });
        }]
    };
});
myApp.directive('dynamic', function ($compile) {
  return {
    restrict: 'A',
    replace: true,
    link: function (scope, ele, attrs) {
      scope.$watch(attrs.dynamic, function(html) {
          html = html.replace(/\$\$([^$]+)\$\$/g, "<span class=\"blue\" mathjax-bind=\"$1\"></span>");
          html = html.replace(/\$([^$]+)\$/g, "<span class=\"red\" mathjax-bind=\"$1\"></span>");
        ele.html(html);
        $compile(ele.contents())(scope);
      });
    }
  };
});
function MyCtrl($scope, $element) {    
    $scope.html = "A coin of is $ \\frac{5}{4} $ thrown $$\\frac{1}{6}$$ dfv";
}
Run Code Online (Sandbox Code Playgroud)

的index.html

<!DOCTYPE html>
<html ng-app="myApp">    
  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML&delayStartupUntil=configured&dummy=.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="http://code.angularjs.org/1.2.7/angular.js" data-semver="1.2.7"></script>
    <script src="app.js"></script>
  </head>
  <body>
  <div ng-controller="MyCtrl">
     <input type="text" ng-model="html"/><br/>
     <div dynamic="html"></div>
  </div>
</body>    
Run Code Online (Sandbox Code Playgroud)

style.css文件

input[type="text"] {
    width: 800px;
}
.red{
    color:red;
    display:inline-block;
}
.blue{
    color:blue;
    display:block;
}
Run Code Online (Sandbox Code Playgroud)