angular ng-bind-html and directive within it

前端 未结 6 1680
北荒
北荒 2020-11-22 11:28

Plunker Link

I have a element which I would like to bind html to it.

That works.

相关标签:
6条回答
  • 2020-11-22 11:47

    Thanks for the great answer vkammerer. One optimization I would recommend is un-watching after the compilation runs once. The $eval within the watch expression could have performance implications.

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

    Here's a forked and updated fiddle.

    0 讨论(0)
  • 2020-11-22 11:50

    For anyone dealing with content that has already been run through $sce.trustAsHtml here is what I had to do differently

    function(scope, element, attrs) {
        var ensureCompileRunsOnce = scope.$watch(function(scope) {
                return $sce.parseAsHtml(attrs.compile)(scope);
            },
            function(value) {
                // when the parsed expression changes assign it into the current DOM
                element.html(value);
    
                // compile the new DOM and link it to the current scope.
                $compile(element.contents())(scope);
    
                // Use un-watch feature to ensure compilation happens only once.
                ensureCompileRunsOnce();
            });
    }
    

    This is only the link portion of the directive as I'm using a different layout. You will need to inject the $sce service as well as $compile.

    0 讨论(0)
  • 2020-11-22 12:04

    Unfortunately I don't have enough reputation to comment.

    I could not get this to work for ages. I modified my ng-bind-html code to use this custom directive, but I failed to remove the $scope.html = $sce.trustAsHtml($scope.html) that was required for ng-bind-html to work. As soon as I removed this, the compile function started to work.

    0 讨论(0)
  • 2020-11-22 12:08

    I was also facing this problem and after hours searching the internet I read @Chandermani's comment, which proved to be the solution. You need to call a 'compile' directive with this pattern:

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

    You can see a working fiddle of it here

    0 讨论(0)
  • 2020-11-22 12:10

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

    Use it like this :

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

    Really easy :)

    0 讨论(0)
  • 2020-11-22 12:11

    Best solution what I've found! I copied it and it work's exactly as I needed. Thanks, thanks, thanks ...

    in directive link function I have

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

    and in directive template:

    <span compile="renderingElement"></span>
    
    0 讨论(0)
提交回复
热议问题