关于javascript:从AngularJS控制器将HTML插入视图

Insert HTML into view from AngularJS controller

是否可以在AngularJS控制器中创建HTML片段并在视图中显示此HTML?

这需要将不一致的JSON blob转换为id : value对的嵌套列表。 因此,HTML是在控制器中创建的,我现在希望显示它。

我创建了一个模型属性,但是如果不打印HTML,则无法在视图中呈现它。

更新

似乎问题来自角度渲染创建的HTML作为引号内的字符串。 将试图找到解决这个问题的方法。

示例控制器:

1
2
3
4
5
6
7
8
9
10
11
12
var SomeController = function () {

    this.customHtml = '
<ul>

<li>
render me please
</li>

</ul>
'
;
}

示例视图:

1
 

给:

1
2
3
4
5
6
7
8
9
   "
<ul>

<li>
render me please
</li>

</ul>
"


对于Angular 1.x,在HTML中使用ng-bind-html

1
 

此时您将收到attempting to use an unsafe value in a safe context错误,因此您需要使用ngSanitize或$ sce来解决此问题。

$ SCE

在控制器中使用$sce.trustAsHtml()转换html字符串。

1
 $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);

ngSanitize

有两个步骤:

  • 包括angular-sanitize.min.js资源,即:


    Angular JS在标记内显示HTML

    上面链接中提供的解决方案对我有用,这个线程没有任何选项。对于任何使用AngularJS版本1.2.9寻找相同内容的人

    这是一份副本:

    Ok I found solution for this:

    JS:

    1
    2
    3
    4
    $scope.renderHtml = function(html_code)
    {
        return $sce.trustAsHtml(html_code);
    };

    HTML:

    1
    2
    <p ng-bind-html="renderHtml(value.button)">
    </p>

    编辑:

    这是设置:

    JS档案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    angular.module('MyModule').controller('MyController', ['$scope', '$http', '$sce',
        function ($scope, $http, $sce) {
            $scope.renderHtml = function (htmlCode) {
                return $sce.trustAsHtml(htmlCode);
            };

            $scope.body = '';

        }]);

    HTML文件:

    1
     


    幸运的是,您不需要任何花哨的过滤器或不安全的方法来避免该错误消息。这是以预期和安全的方式在视图中正确输出HTML标记的完整实现。

    必须在Angular之后包含sanitize模块:

    1
    2
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-sanitize.js">

    然后,必须加载模块:

    1
    2
    3
    angular.module('app', [
      'ngSanitize'
    ]);

    这将允许您在控制器,指令等的字符串中包含标记:

    1
    scope.message ="42 is the answer.";

    最后,在模板中,它必须像这样输出:

    1
    2
    <p ng-bind-html="message">
    </p>

    这将产生预期的输出:42是答案。


    我今天试过,我找到的唯一方法就是这个


    ng-bind-html-unsafe不再有效。

    这是最短的方式:

    创建一个过滤器:

    1
    myApp.filter('unsafe', function($sce) { return $sce.trustAsHtml; });

    在你看来:

    1
     

    附:此方法不要求您包含ngSanitize模块。


    在HTML上

    1
     

    要么

    1
    </div

    在控制器上

    1
    2
    3
    mySceApp.controller("myAppController", function myAppController( $sce) {

    this.myCtrl.comment.msg = $sce.trustAsHtml(html);

    适用于$scope.comment.msg = $sce.trustAsHtml(html);


    我发现使用ng-sanitize不允许我在html中添加ng-click。

    为了解决这个问题我添加了一个指令像这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    app.directive('htmldiv', function($compile, $parse) {
    return {
      restrict: 'E',
      link: function(scope, element, attr) {
        scope.$watch(attr.content, function() {
          element.html($parse(attr.content)(scope));
          $compile(element.contents())(scope);
        }, true);
      }
    }
    });

    这是HTML:

    1
    <htmldiv content="theContent"></htmldiv>

    祝好运。


    刚刚通过遵循angular(v1.4)文档使用ngBindHtml做到了这一点,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    and expression can be"
    <ul>

    <li>
    render me please
    </li>

    </ul>
    "

    确保在模块的依赖项中包含ngSanitize。
    那它应该工作正常。


    另一种解决方案,与blrbr非常相似,只是使用scoped属性是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    angular.module('app')
    .directive('renderHtml', ['$compile', function ($compile) {
        return {
          restrict: 'E',
          scope: {
            html: '='
          },
          link: function postLink(scope, element, attrs) {

              function appendHtml() {
                  if(scope.html) {
                      var newElement = angular.element(scope.html);
                      $compile(newElement)(scope);
                      element.append(newElement);
                  }
              }

              scope.$watch(function() { return scope.html }, appendHtml);
          }
        };
      }]);

    然后

    1
    <render-html html="htmlAsString"></render-html>

    请注意,您可以用element.replaceWith()替换element.append()


    使用角度创建新属性或指令,还有一个解决此问题的方法。

    产品specs.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     <h4>Specs</h4>
            <ul class="list-unstyled">
             
    <li>

                Shine
                : {{product.shine}}
    </li>

             
    <li>

                Faces
                : {{product.faces}}
    </li>

             
    <li>

                Rarity
                : {{product.rarity}}
    </li>

             
    <li>

                Color
                : {{product.color}}
    </li>

           
    </ul>

    app.js

    1
    2
    3
    4
    5
    6
    7
    8
     (function() {
    var app = angular.module('gemStore', []);    
    app.directive("    ", function() {
    return {
      restrict: 'E',
      templateUrl:"product-specs.html"
    };
    });

    的index.html

    1
     <product-specs>  </product-specs>//it will load product-specs.html file here.

    要么

    1
    //it will add product-specs.html file

    要么

    1
     

    https://docs.angularjs.org/guide/directive


    你也可以使用ng-include。

    1
     

    您可以使用"ng-show"来显示隐藏此模板数据。