如何使用AngularJS模板渲染HTML


68

这是我的模板:

<div class="span12">
  <ng:view></ng:view>
</div>

这是我的视图模板:

<h1>{{stuff.title}}</h1>

{{stuff.content}}

我得到的content是html,我想在视图中显示它,但是我得到的只是原始的html代码。如何呈现HTML?


2
HTML来自哪里?在不同的情况下,你会想ngBindHtmlUnsafengSanitize或自定义指令。
Josh David Miller

该html来自我的数据库
user194932147

1
内容绝对可信吗?
乔什·大卫·米勒

1
例如,如果HTML包含script标签,则浏览器将执行该标签。这种类型的“注入”攻击是损坏应用程序和窃取用户数据的常用方法。AngularJS有一个单独的模块ngSanitize,您可以使用它剥离任何危险标签的HTML。它还有一个称为的指令ngBindHtml,其作用与相同ngBindHtmlUnsafe,但会为您剥离危险标签。如果内容完全属于您-而不是来自用户或第三方-那么您就不需要它。
Josh David Miller

Answers:


100

采用-

<span ng-bind-html="myContent"></span>

您需要告诉angular不要逃避它。


10
AngularJS 1.2中的API已更改。 stackoverflow.com/questions/18340872/...
amccausl

2
由于有角度的“ hell docs”,amccausl已为新的角度使用者节省了无数小时的调试时间,不建议使用ng-bind-html-unsafe,请参阅上面注释中的链接以解决问题。
rjm226 2013年

1
我只是将<span ng-bind-html =“ myHtmlFragment”> </ span>插入模板中,却没有做任何其他事情,效果很好。我不必注入$ sce。这是文档:docs.angularjs.org/api/ng/directive/ngBindHtml
Joseph Sheedy

1
ngSanitize-使用此处的答案时(我可以从ng-bind-html上的有关角度的文档中获得)缺少的一件事是您需要确保您的应用程序包含ngSanitize模块。没有它,它就无法工作。
杰米2015年

1
ng-bind-html独自工作而未使用trustAsHtml
Marco Lackovic

50

为此,我使用了自定义过滤器。

在我的应用中:

myApp.filter('rawHtml', ['$sce', function($sce){
  return function(val) {
    return $sce.trustAsHtml(val);
  };
}]);

然后,在视图中:

<h1>{{ stuff.title}}</h1>

<div ng-bind-html="stuff.content | rawHtml"></div>

1
这是@Daniel的出色解决方案。如果我使用$sce.trustAsHtml,则不需要包括ngSanitize对app模块的依赖关系吗?我正在使用Angular 1.3
Neel

我们可以使用ng-include来实现吗?
张昌望2015年

这对我不起作用,我使用的是角度7。请提出解决方案。谢谢。
Kamlesh

3

您应该遵循Angular文档并使用$ sce-$ sce是一项为AngularJS提供严格的上下文转义服务的服务。这是一个文档:http ://docs-angularjs-org-dev.appspot.com/api/ng.directive: ngBindHtmlUnsafe

让我们以异步加载Eventbrite登录按钮为例

在您的控制器中:

someAppControllers.controller('SomeCtrl', ['$scope', '$sce', 'eventbriteLogin', 
  function($scope, $sce, eventbriteLogin) {

    eventbriteLogin.fetchButton(function(data){
      $scope.buttonLogin = $sce.trustAsHtml(data);
    });
  }]);

在您的视图中,只需添加:

<span ng-bind-html="buttonLogin"></span>

在您的服务中:

someAppServices.factory('eventbriteLogin', function($resource){
   return {
        fetchButton: function(callback){
            Eventbrite.prototype.widget.login({'app_key': 'YOUR_API_KEY'}, function(widget_html){
                callback(widget_html);
            })
      }
    }
});

3

在angular 4+中,我们可以使用innerHTMLproperty代替ng-bind-html

就我而言,它正在工作,并且我正在使用angular 5

<div class="chart-body" [innerHTML]="htmlContent"></div>

In.ts文件

let htmlContent = 'This is the `<b>Bold</b>` text.';

2

因此,也许您希望在index.html中包含此文件,以加载库,脚本并使用视图初始化应用程序:

<html>
  <body ng-app="yourApp">
    <div class="span12">
      <div ng-view=""></div>
    </div>
    <script src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script>
    <script src="script.js"></script>
  </body>
</html>

然后yourView.html可能只是:

<div>
  <h1>{{ stuff.h1 }}</h1>
  <p>{{ stuff.content }}</p>
</div>

scripts.js可能会使您的控制器具有$ scope的数据。

angular.module('yourApp')
    .controller('YourCtrl', function ($scope) {
      $scope.stuff = {
        'h1':'Title',
        'content':"A paragraph..."
      };
    });

最后,您必须配置路由并分配控制器以查看其$ scope(即您的数据对象)

angular.module('yourApp', [])
.config(function ($routeProvider) {
  $routeProvider
    .when('/', {
      templateUrl: 'views/yourView.html',
      controller: 'YourCtrl'
    });
});

我没有测试过,很抱歉,如果有错误,但是我认为这是Angularish获取数据的方式


如果我想要相同的行为但不依赖routeProvider怎么办?
拉斐尔·伊西德罗

使用ui-router是相同的,只是它是$ stateProvider而不是$ routeProvider和.state('yourState',{url:'/',templateUrl:'yourView.html',控制器:'YourCtrl'});
irth 2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.