如何使ng-bind-html编译angularjs代码

时间:2013-11-01 11:49:11

标签: javascript html angularjs web

我正在使用angularjs 1.2.0-rc.3。我想动态地将html代码包含到模板中。为此我在控制器中使用:

html = "<div>hello</div>";
$scope.unicTabContent = $sce.trustAsHtml(html);

在我得到的模板中:

<div id="unicTab" ng-bind-html="unicTabContent"></div>

它适用于常规HTML代码。但是当我尝试放置角度模板时,它没有被解释,它只是包含在页面中。例如,我想包括:

<div ng-controller="formCtrl">
    <div ng-repeat="item in content" ng-init="init()">
    </div>
</div>

非常感谢

8 个答案:

答案 0 :(得分:75)

此解决方案不使用硬编码模板,您可以编译嵌入在API响应中的Angular表达式。

第1步。 安装此指令:https://github.com/incuna/angular-bind-html-compile

第2步。在模块中包含该指令。

angular.module("app", ["angular-bind-html-compile"])

第3步。在模板中使用该指令:

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

<强>结果:

控制器对象

 $scope.letter = { user: { name: "John"}}

JSON响应

{ "letterTemplate":[
    { content: "<span>Dear {{letter.user.name}},</span>" }
]}

HTML输出=

<div bind-html-compile="letterTemplate.content"> 
   <span>Dear John,</span>
</div>

供参考,这里是相关指令:

(function () {
    'use strict';

    var module = angular.module('angular-bind-html-compile', []);

    module.directive('bindHtmlCompile', ['$compile', function ($compile) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                scope.$watch(function () {
                    return scope.$eval(attrs.bindHtmlCompile);
                }, function (value) {
                    element.html(value);
                    $compile(element.contents())(scope);
                });
            }
        };
    }]);
}());

答案 1 :(得分:18)

这就是我所做的,不知道它是否是的角度方式 TM < / sup>,但它有效并且非常简单;

.directive('dynamic', function($compile) {
    return {
        restrict: 'A',
        replace: true,
        link: function (scope, element, attrs) {
            scope.$watch(attrs.dynamic, function(html) {
                $compile(element.html(html).contents())(scope);
            });
        }
    };
});

因此;

<div id="unicTab" dynamic="unicTabContent"></div>

编辑:我找到了角度方式,它的超级很简单。

$templateCache.put('unicTabContent', $sce.trustAsHtml(html));
<div id="unicTab" ng-include="'unicTabContent'"></div>

不需要制定自己的指令或任何东西。 但它是一种绑定一次的交易,it wont see changes made to your html就像the custom directive does一样。

答案 2 :(得分:2)

正如Vinod Louis在评论中所说,最好的方法是使用模板。我必须在常规代码之外定义一个模板,例如我在index.html中添加了代码:

<script type="text/ng-template" id="unic_tab_template.html">
    <div ng-switch on="page">
        <div ng-switch-when="home"><p>{{home}}</p></div>
        <div ng-switch-when="form">
            <div ng-controller="formCtrl">
                <div ng-repeat="item in content">{{item.name}}:{{item.value}}</div>
            </div>
        </div>
        <div ng-switch-default>an error accured</div>
    </div>
</script>

此模板是有条件的,因此根据$ scope.page的值,它在3个模板之间切换(第三个是错误处理程序)。为了使用它,我有:

<div id="unicTab" ng-controller="unicTabCtrl">
    <div ng-include="'unic_tab_template.html'"></div>
</div>

这样我的页面会根据unicTabCtrl控制器中的$ scope而改变。

总结插入angularsjs模板接缝的想法难以实现($ compile接缝是解决方案,但我无法使其工作)。但您可以使用条件模板。

答案 3 :(得分:2)

我试图做同样的事情并遇到了这个模块。

http://ngmodules.org/modules/ng-html-compile

我刚刚加入它然后我能够使用“ng-html-compile”而不是“ng-bind-html”

答案 4 :(得分:1)

一种方法是使用指令来插入包含角度表达的自定义模板

<div id="unicTab" unic-tab-content></div>
 
app.directive("unicTabContent",function(){
   return {
      restrict:"A",
      template:'{{unicTabContent}}'
   }
})

答案 5 :(得分:1)

我在不使用模板的情况下解决当前应用中的类似问题(不优雅,但正常工作):

directive('ngBindHtmlCompile', ['$compile', function ($compile) {
    return {
        restrict: 'A',
        compile: function compile(tElement, tAttributes, transcludeFn) {
            return function postLink(scope, element, attributes) {
                scope.$watch(function() {
                    return scope.$eval(attributes.ngBindHtml);
                }, function(newValue, oldValue) {
                    $compile(element.children())(scope);
                });
            };
        }
    };
}]);

在同一元素上需要ngBindHtml,并在使用ngBindHtml更改元素内容后对其进行编译。

<div id="unicTab" ng-bind-html="unicTabContent" ng-bind-html-compile></div>

ng-html-compile看起来很相似,但乍一看,当模板内容发生变化时,不会重新计算。但我还没试过。

答案 6 :(得分:0)

使用Angular的内置$ interpolate和$ sce对象,下面的代码更加简单。首先将$ interpolate和$ sce Angular对象注入到您的指令中,因为您在指令中执行任何自定义操作。

amqApp.directive('myDir', ['$interpolate', '$sce', function ($interpolate,$sce ) {...}

然后创建导入的html表达式中找到的所有范围变量......

$scope.custom = 'Hello World';

接下来使用$ interpolate处理您的自定义HTML及其表达式...然后确保在绑定之前使用$ sce对象将其信任为HTML ...

var html = $interpolate('<b>{{custom}}</b>')($scope);    
$scope.data = $sce.trustAsHtml(html);

最后,在您看来,只需确保使用带有&#34; ng-bind&#34;的元素。或&#34; ng-bind-html&#34;在你的视图显示中。我发现$ sce片段不会将HTML显示为HTML(将其视为文本),如果你不在你的html模板中绑定它......

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

你应该用粗体看......

Hello World

我使用此技巧从web.config中使用自定义角度{{expressions}}导入文本/ HTML。

答案 7 :(得分:0)

基于内置模板的@ clement-roblot的许多简化解决方案。

控制器:

app.controller('TestCtrl', [
    '$scope',
    '$templateCache',
    function ($scope, $templateCache) {
        $templateCache.put('test.html', '2 + 2 = {{ 2 + 2 }}');
    }
]);

查看:

<div ng-include="'test.html'"></div>