programing

Angular로 변경한 후 MathJax를 업데이트하는 중JS 모형

copyandpastes 2023. 3. 27. 22:01
반응형

Angular로 변경한 후 MathJax를 업데이트하는 중JS 모형

Angular를 사용하려고 합니다.Latex 스타일 방정식을 포함하는 JS 이원 바인딩 텍스트.방정식을 포맷하기 위해 MathJax를 호출하고 싶지만 MathJax가 Angular 뒤에 호출되는지 확인할 수 있는 최선의 방법을 모르겠습니다.JS가 모델 변경을 마칩니다.콜백이 필요할 것 같아요다음은 내 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} \\)';

}

다음은 제 HTML입니다.

<div ng-controller="MyCtrl">
    <button ng-click="Update()">Update</button>
  {{Expression}}
</div>

Findle은 http://jsfiddle.net/LukasHalim/UVjTD/1/에 있습니다.업데이트 버튼을 두 번 클릭해도 원래 표현은 삭제되지 않고 버그나 충돌처럼 보입니다.

MathJax와 싸우는 데 많은 날(아마도 몇 주)을 허비했기 때문에, 저는 MathJax의 다양한 기호가 순식간에 업데이트되는 것에 너무 익숙합니다.저는 Angular에 처음 와보는 사람입니다만, 이 일로 인해, 제 문제를 해결할 수 있는 솔루션을 얻을 수 있었습니다.당신의 문제도 해결되었으면 합니다.

라이브 데모: jsfiddle


Angular가 제공하는 일반 보간법을 사용하는 대신, 저는 새로운 명령을 만들었습니다.mathjax-bind.

ifexpression는 수학입니다.\( {{expression}} \)이치노

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

모든 것은 적절한 시기에 조판되어 갱신됩니다.

디렉티브의 지원 코드는 다음과 같습니다.

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]]);
            });
        }]
    };
});

가장 단순하고 빠르고 안정적인 솔루션:

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

장점:

  • 간단하게 셋업 할 수 있습니다.이 코드를 복사하기만 하면 됩니다.
  • 페이지에 있는 모든 것이 활자로 되어 있습니다.
  • 다른 솔루션보다 훨씬 빠르게 렌더링할 수 있습니다.한 번에 페이지를 렌더링할 수 있기 때문입니다.다른 답변은 한 항목이 완료될 때까지 다음 항목을 타이핑할 때까지 기다립니다.예를 들어 여러 개가 있는 경우 렌더링 속도가 느려집니다.mathjax-bind예요.이 점이 제가 다른 답을 찾고 있었던 이유입니다.
  • mathjax 설정에서 "ignoreClass" 옵션을 사용하여 요소를 쉽게 제외할 수 있습니다.

★★★★★★★★★★mathjax-bind디렉티브는 63초 걸렸지만 이 방법에서는 페이지를 렌더링하는 데 1.5초가 걸렸습니다.이 함수는 다이제스트 사이클마다 호출되기 때문에 많이 실행되는 것으로 알고 있습니다만, 페이지가 눈에 띄게 느려지는 것은 아닙니다.

나는 벤 앨퍼트의 대답에 따라 간단한 바이올린을 만들었다.여기 바이올린플랭크입니다.

특히 텍스트에 Mathjax에서 변환할 부분만 있는 경우 이 기능을 사용할 수 있습니다.인라인 mathjax의 경우 텍스트를 $로 둘러싸야 하며 블록 표시의 경우 블록을 $$로 둘러싸야 합니다(해당 regex를 작성할 경우 원하는 형식을 사용할 수 있습니다).

app.module

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";
}

index.displaces를 표시합니다.

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

style.css

input[type="text"] {
    width: 800px;
}
.red{
    color:red;
    display:inline-block;
}
.blue{
    color:blue;
    display:block;
}

http://jsfiddle.net/pz5Jc/ 를 참조해 주세요.

템플릿:

    {{Label}} <span id="mathElement">{{Expression}}</span>

컨트롤러 내:

$scope.Update = function() {
    $scope.Expression = '\\frac{9}{4} \\div \\frac{1}{6}';
    $scope.Label = 'Updated Expression:'
    var math = MathJax.Hub.getAllJax("mathElement")[0];
    math.Text('\\frac{4}{4} \\div \\frac{2}{6}');
}

몇 가지 포인트:

수학잭스는 잘 모르지만

  • 식에서 라벨을 분할하면 식을 직접 사용할 수 있습니다.
  • 식을 강제로 새로 고치려면 DOM 요소를 수동으로 선택해야 합니다.이것은 유감스럽지만, mathjax가 식을 구문 분석(및 자체 DOM 요소 삽입)하면 각 바인딩 밖으로 요소를 밀어냅니다.
  • 여기서 수정은 올바른 산술적 요소를 선택하고 텍스트 변경 함수를 호출하여 식을 업데이트하는 것입니다.

이 명령어는 식 내에서 이중 컬리 마크업을 사용할 수 있도록 합니다(또한 스코프에서 식 변수를 설정할 필요가 없습니다).MathJax만 지원하며 컴파일된 DOM을 저장하여 범위 변수의 변경 사항을 업데이트한다는 점을 제외하고 이 블로그 게시물을 기반으로 합니다.

알렉스 오스본이 말했듯이 수학과 비수학을 분리하는 것이 가장 좋습니다.

사용방법:

<p>This is inline math: <latex>x^{ {{power}} }</latex>, 
and this is display math: <div latex> y^{ {{power}} } .</div></p>

개요:

angular.module('app', [])
  .controller('ctrl', function($scope) {
    $scope.power = "\\sin(x^2)";
  })
  .directive('latex', function() {
    return {
      restrict: 'AE',
      link: function(scope, element) {
        var newDom = element.clone();
        element.replaceWith(newDom);
        var pre = "\\(",
          post = "\\)";
        if (element[0].tagName === 'DIV') {
          pre = "\\[";
          post = "\\]";
        }
        scope.$watch(function() {
          return element.html();
        }, function() {
          console.log(element);
          newDom.html(pre + element.html() + post);
          MathJax.Hub.Typeset(newDom[0]);
        });
      }
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

<div ng-app="app" ng-controller="ctrl">
  <p>Power:
    <input ng-model="power" />
  </p>
  <p>This is the inline latex,
    <latex>x^{ {{power}} }</latex>, followed by some display mode latex
    <div latex>y^{ {{power}} } = {{power}}.</div>And that's it!
  </p>
</div>

간단한 해결책은 $timeout을 사용하여MathJax.Hub.Queue(["Typeset", MathJax.Hub])브라우저 이벤트 대기열에 있습니다(DOM 렌더링이 완료된 후 지시문 실행 참조).

다음과 같은 경우:

            var app = angular.module('myApp', []);
            app.controller('myController', function ($scope, $timeout) {
                controller = this;

                $scope.Update = function () {
                    $scope.value = " \\( \\frac{5}{4} \\div \\frac{1}{6} \\)";
                    $timeout(controller.updateMathJax, 0);
                }

                this.updateMathJax = function () {
                    MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
                }
            });

당신은 나의 수정으로 시도할 수 있습니다.http://jsfiddle.net/bmma8/4/ modify input 또는 버튼을 클릭하면 당신의 표현이 갱신됩니다.

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

및 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>

알렉산드르

저는 사실 다른 해결책을 생각해 냈습니다.일부 각도 및 연산을 렌더링할 때는 다음과 같이 수행합니다.

각도 제어 장치

$scope x = 5;

HTML

<h3> {{ '$ Multiplication = '+ x + ' * 2 =' + (x*2) + '$'}} </h3>

공식화된 산술 잭스 결과

곱셈 = 5 * 2 = 10

중요한 것은 괄호 안에 달러 기호를 텍스트로 포함시키는 것입니다.Angular가 렌더링할 때는 달러 기호가 일반 텍스트로 표시되지만, Math Jax 형식이 실행되면 달러 기호가 인식되어 마법을 실행합니다.

이에 대한 지침을 구축합니다.

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

HTML

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

자바스크립트

 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]);
            });
        }
    }
});

나는 로니의 해결책을 조금 더 만지작거렸다.디스플레이 산술은 디스플레이 모드로 표시되어야 합니다.

<script type="math/tex; mode=display">

나는 그것을 나타내기 위해 생성된 스팬에 속성을 추가했다.

Fidle은 http://jsfiddle.net/repa/aheujhfq/8/에 있습니다.

언급URL : https://stackoverflow.com/questions/16087146/getting-mathjax-to-update-after-changes-to-angularjs-model

반응형