2014-10-27 56 views
2

在我正在處理的應用程序中,服務爲應用程序提供包含HTML的json。我的HTML輸出的模板是這樣的:ng-bind-html中的AngularJS指令

<div ng-bind-html="renderHtml(widget.article.body)"></div> 

此HTML可能包含自定義指令,例如直列圖表:

directiveModule.directive('inlineChart', function(){ 
    return { 
     restrict: 'A', 
     scope: { inline-widget:'=elem' }, 
     template: '<p ng-bind="inline-widget.blah"></p>' 
    }; 
}); 

如果我在模板中正常使用的指令,一切工作正常,但在使用ngHing-html和renderHtml函數時,它似乎沒有被觸及。

任何建議如何實現這一點非常感謝!

+0

您是否包含['ngSanitize'](https://docs.angularjs.org/api/ngSanitize)模塊? renderHTml函數在哪裏? – PSL 2014-10-27 18:18:13

回答

1

您需要導入ngSanitize模塊並使用$sce服務。它應該是這個樣子:

// Remember the following comes from angular-sanitize.js found on the angular website and 
// also must be included in the web app. 
angular.module('myApp', ['ngSanitize']); 
angular.module('myApp') 
    .controller('MyCtrl', function($scope, $sce) { 
    //... other controller code 
    $scope.renderHtml = function(html) { 
     return $sce.trustAsHtml(html); 
    }; 
    }); 

總之,$sce服務將迎來HTML作爲值得信賴的。你可以找到文件here

編輯:我意識到我可能沒有回答這個問題。看起來你問的是綁定作用域變量到你的指令中呈現的指令嗎?爲了讓元素正確編譯,你將不得不使用$compile服務並改變你的邏輯。首先,模板:

<p class="place-directive-here"></p> 

然後指令:

angular.module('myApp') 
    .directive('myDirective', function($compile) { 
    return { 
     scope: { 
     inlineWidget: '=' 
     }, 
     template: '<p class="place-directive-here"></p>', 
     link: function(scope, elem, attrs) { 
     var placement = elem.find('.place-directive-here'); 
     scope.$watch('inlineWidget', function(widget){ 
      if(!widget){ 
      return; 
      } 
      // Compile the html against the scope. This will bind the dom to your 
      // current scope 
      var newElement = $compile(widget.blah)(scope); 
      // Place in the view 
      placement.html(newElement); 
     }); 
     } 
    }; 
    }); 

您可以找到編譯文檔here。希望這是一個更全面的答案,你在找什麼。

編輯2:爲了澄清,指令應該是這樣的網頁上:

<div my-directive inline-widget="someInlineWidget"></div> 

place-directive-here類只是一個用於指令找出你<p>標籤和渲染它的內側把手。但是,如果角度不與被的my-directive內呈現的HTML而言,我們提供的第一個解決方案應該只是罰款和my-directive模板屬性應該是:

template: '<p ng-bind-html="renderHtml(inlineWidget.blah)"></p>' 
+0

我不太明白你的意思是「place-directive-here」。如果該指令在您的示例中被稱爲「myDirective」,是否應該只是「我的指令」? – mhanisch 2014-10-28 11:20:33

+0

這個問題似乎是,角度是不尋找在呈現的HTML裏面的自定義指令。您寫的指令中的'link'部分從未被激活:( – mhanisch 2014-10-28 11:47:22

+0

對不起,第一個解決方案應該可以工作了,然後我再添加一個編輯以進行澄清 – Mike 2014-10-28 16:03:50

6

https://stackoverflow.com/a/31880192/1345244

添加該指令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> 

真的很容易:)

+0

工程就像一個魅力!謝謝! – Asimov4 2015-10-04 19:01:58

+0

請注意,您可以使用相同的範圍編譯多個($ watch)不同的html。每當$ watch值發生變化時,您應該創建新的子範圍並銷燬前一個範圍。 – Mat 2016-10-21 07:59:10

0

HTML標籤角指令其屬性的一個例子

查看工作例如在Plunker

這個例子說明如何創建md-card以內directivetitlecontent,並且具有錨內容標籤<a>

使用$sce.trustAsHtmllink作爲$sce作品時,它必然要scope

HTML

<div ng-app="myApp"> 
    <my-app-card title="Card Title" content="Card Content with anchor <a href='http://www.google.com' target='_blank'> Google </a>"></my-app-card> 
</div> 

JS

var app = angular.module("myApp",['ngMaterial']) 
    .directive ('myAppCard', ['$sce', function($sce){ 
     return { 
      scope:{ title:"@title", content:"@content"}, 
      link : function(scope, element, attr) { 
       var hcont = $sce.trustAsHtml(attr.content); 
       var html = "<md-card><md-card-content><h2>"+ attr.title + "</h2><p>"+ hcont +"</p></md-card-content></md-card>"; 
       scope.$watch('myAppCard', function() { 
         element.append(html); 
        } 
       ) 
      } 
     } 
}]);