96

プランカーリンク

HTMLをバインドしたい要素があります。

<div ng-bind-html="details" upper></div>

それはうまくいきます。さて、それに加えて、バインドされた html にバインドされたディレクティブもあります。

$scope.details = 'Success! <a href="#/details/12" upper>details</a>'

upperただし、 div とアンカーを含むディレクティブは評価されません。どうすれば機能しますか?

4

6 に答える 6

187

私もこの問題に直面しており、何時間もインターネットを検索した後、@Chandermani のコメントを読み、それが解決策であることがわかりました。このパターンで「コンパイル」ディレクティブを呼び出す必要があります。

HTML:

<div compile="details"></div>

JS:

.directive('compile', ['$compile', function ($compile) {
    return function(scope, element, attrs) {
        scope.$watch(
            function(scope) {
                // watch the 'compile' expression for changes
                return scope.$eval(attrs.compile);
            },
            function(value) {
                // when the 'compile' expression changes
                // assign it into the current DOM
                element.html(value);

                // compile the new DOM and link it to the current
                // scope.
                // NOTE: we only compile .childNodes so that
                // we don't get into infinite loop compiling ourselves
                $compile(element.contents())(scope);
            }
        );
    };
}])

ここで動作するフィドルを見ることができます

于 2013-07-02T13:14:01.567 に答える
36

vkammerer さん、すばらしい回答をありがとうございます。私がお勧めする最適化の 1 つは、コンパイルが 1 回実行された後に監視を解除することです。ウォッチ式内の $eval は、パフォーマンスに影響を与える可能性があります。

    angular.module('vkApp')
  .directive('compile', ['$compile', function ($compile) {
      return function(scope, element, attrs) {
          var ensureCompileRunsOnce = scope.$watch(
            function(scope) {
               // watch the 'compile' expression for changes
              return scope.$eval(attrs.compile);
            },
            function(value) {
              // when the 'compile' expression changes
              // assign it into the current DOM
              element.html(value);

              // compile the new DOM and link it to the current
              // scope.
              // NOTE: we only compile .childNodes so that
              // we don't get into infinite loop compiling ourselves
              $compile(element.contents())(scope);

              // Use un-watch feature to ensure compilation happens only once.
              ensureCompileRunsOnce();
            }
        );
    };
}]);

これは、フォークされて更新されたフィドルです。

于 2013-12-06T17:57:18.130 に答える
28

このディレクティブangular-bind-html-compileを追加します

.directive('bindHtmlCompile', ['$compile', function ($compile) {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      scope.$watch(function () {
        return scope.$eval(attrs.bindHtmlCompile);
      }, function (value) {
        // Incase value is a TrustedValueHolderType, sometimes it
        // needs to be explicitly called into a string in order to
        // get the HTML string.
        element.html(value && value.toString());
        // If scope is provided use it, otherwise use parent scope
        var compileScope = scope;
        if (attrs.bindHtmlScope) {
          compileScope = scope.$eval(attrs.bindHtmlScope);
        }
        $compile(element.contents())(compileScope);
      });
    }
  };
}]);

次のように使用します。

<div bind-html-compile="data.content"></div>

本当に簡単です:)

于 2015-08-07T14:28:43.163 に答える
13

残念ながら、コメントするほどの評判はありません。

私はこれを何年も機能させることができませんでした。このカスタム ディレクティブを使用するようにコードを変更しましたが、ng-bind-html が機能するために必要なng-bind-htmlを削除できませんでした。$scope.html = $sce.trustAsHtml($scope.html)これを外すとすぐにコンパイル機能が動き始めました。

于 2014-07-23T12:04:07.290 に答える
-2

私が見つけた最良の解決策!私はそれをコピーしましたが、それはまさに私が必要としていたものです。ありがとう、ありがとう、ありがとう...

私が持っているディレクティブリンク機能で

app.directive('element',function($compile){
  .
  .
     var addXml = function(){
     var el = $compile('<xml-definitions definitions="definitions" />')($scope);
     $scope.renderingElement = el.html();
     }
  .
  .

およびディレクティブ テンプレートで:

<span compile="renderingElement"></span>
于 2014-03-20T13:37:32.927 に答える