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



我正在使用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>

多谢

此解决方案不使用硬编码模板,您可以编译嵌入在 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"}}

杰伦响应

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

这就是我所做的,不知道它是否是角度方式TM,但它有效并且超级简单;

.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>

不需要制定自己的指令或任何东西。但这是一种绑定一次的交易,它不会像自定义指令那样看到对 html 所做的更改。

正如Vinod Louis在他的评论中所说,最好的方法是使用模板。我必须在常规代码之外定义一个模板,例如,我在索引中添加了该代码.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接缝是解决方案,但我无法让它工作)。但相反,您可以使用条件模板。

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

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

只是包含了它,然后我能够使用"ng-html-compile"而不是"ng-bind-html"

我在不使用模板的情况下解决当前应用程序中类似问题的解决方案(不优雅,但有效):

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看起来很相似,但乍一看,当模板内容更改时,它不会重新计算。但我还没有尝试过。

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

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

下面的代码使用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);

最后,在您的视图中,只需确保在视图显示中使用带有"ng-bind"或"ng-bind-html"的元素。我发现如果您不像这样在 html 模板中绑定它,$sce块不会将 HTML 显示为 HTML(将其视为文本)......

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

您应该以粗体显示...

世界您好

我使用这个技巧从web.config导入带有自定义角度{{表达式}}的文本/HTML。

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

控制器:

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

视图:

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

最新更新