在Angular指令中使用$compile来处理外部模板(templateURL)

49

我有一个递归的Angular指令,使用模板变量并在link函数中编译。

问题是,我的模板已经变得非常长而且难以控制,我想将它外部化到一个外部HTML文件中(这也会让自动缩进更容易)。

如何将外部模板加载到指令中,以便可以在$compile内使用?

我看到过templateURL,但这不能让我命名该变量并将其传递给$compile函数。

var template = 
           "<p>My template</p>"+
           "<this-directive val='pass-value'></this-directive>";

return {
     scope: {
     ...
     },
     ...
     link: function(scope, element){
            element.html(template);
            $compile(element.contents())(scope);
        }
}
2个回答

109

你可以使用$templateRequest服务来获取模板。这是一个方便的服务,还将模板缓存到$templateCache中,以便只发出对template.html的单个请求。

作为说明(而不涉及递归指令问题),用法如下:

link: function(scope, element){
   $templateRequest("template.html").then(function(html){
      var template = angular.element(html);
      element.append(template);
      $compile(template)(scope);
   });
};

plunker(检查网络选项卡以查看单个网络请求)


11
太棒了!你是我的英雄!我能请你喝杯咖啡吗? - CodyBugstein
我很好奇,在你的示例中是否可以在“template.html”中使用HTML绑定(ng-bind-html)?我无法使其正常工作。 - zhekaus
1
@zhekaus,是的,但你仍然需要使用通常的ngSanitize/$sanitize或者使用$sce.trustAsHtml - New Dev
你知道为什么每当它被转换为字符串或控制台记录时,它似乎无法编译吗? - A Star
只是好奇,是否有一种方法可以为template.html维护双向绑定? - AshD

3

如果模板的大小较大,我更喜欢使用$http来加载:

$http.get('mytemp.html').then(function(response) {
            element.html(response.data);
            $compile(element.contents())(scope);
            });

1
你应该缓存加载的模板,像这样 $http.get('mytem.html', {cache: $templateCache}).then(function(response) { element.html(response.data); $compile(element.contents())(scope); }) - Leonardo
1
代码中缺少一个括号,但我无法编辑,因为它少于6个字符 :) - Leonardo
5
$templateRequest服务运行安全检查,然后使用$http下载提供的模板,并在成功后将内容存储在$templateCache中。$templateCache使用$http执行附加操作的一行代码。我唯一看到的区别是模板没有放入$templateCache中,这是你的代码目的吗? - felix at housecat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接