53

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

非常感谢

4

8 回答 8

79

此解决方案不使用硬编码模板,您可以编译嵌入在 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);
                });
            }
        };
    }]);
}());
于 2015-05-01T20:23:00.060 回答
19

这就是我所做的,不知道它是否是角度方式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 所做的更改

于 2016-02-10T03:27:13.390 回答
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 seams 是解决方案,但我无法使其工作)。但是,您可以使用条件模板。

于 2013-11-02T13:25:45.957 回答
2

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

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

我刚刚包含它,然后我能够使用“ng-html-compile”而不是“ng-bind-html”

于 2015-01-28T21:16:05.087 回答
1

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

<div id="unicTab" unic-tab-content></div>
app.directive("unicTabContent",function(){
   return {
      restrict:"A",
      template:'{{unicTabContent}}'
   }
})
于 2013-11-01T11:58:49.177 回答
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看起来很相似,但乍一看它不会在模板内容发生变化时重新计算。但我还没有尝试过。

于 2015-11-20T11:13:57.830 回答
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);

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

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

你应该看到粗体...

你好世界

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

于 2017-10-22T22:17:52.113 回答
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>
于 2018-07-13T07:15:11.763 回答