8

我正在尝试通过范围变量传入模板的 url。范围不会改变,因此模板不需要根据它进行更新,但目前范围变量始终未定义。

<div cell-item template="{{col.CellTemplate}}"></div>

理想情况下,该指令是:

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
        return {
            scope: {
                template: '@template'
            },
            templateUrl: template // or {{template}} - either way
        };
    }])

然而,这不起作用。我已经尝试了很多不同的排列来完成相同的概念,这似乎是最接近的,但它仍然不起作用。

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
        return {
            scope: {
                template: '@template'
            },
            link: function (scope, element, attrs) {
                var templateUrl = $parse(attrs.template)(scope);
                $http.get(templateUrl, { cache: $templateCache }).success(function (tplContent) {
                    element.replaceWith($compile(tplContent)(scope));
                });
            }
        };
    }])

我也尝试过使用 ng-include,但这也不会在编译之前评估范围变量。CellTemplate 值来自数据库调用,因此在评估之前完全未知。任何让这项工作的建议将不胜感激!

编辑:我正在使用 angular 1.0.8 并且无法升级到更新版本。

4

3 回答 3

14

你一点也不遥远。

您不需要为指令使用隔离范围。您可以像这样传递 templateUrl:

<div cell-item template="col.CellTemplate"></div>

然后添加一个手表来检测模板值何时发生变化:

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
        return {
            restrict: 'A',
            link: function(scope , element, attrs) {

              scope.$watch(attrs.template, function (value) {
                if (value) {
                  loadTemplate(value);
                }
              });

              function loadTemplate(template) {
                  $http.get(template, { cache: $templateCache })
                    .success(function(templateContent) {
                      element.replaceWith($compile(templateContent)(scope));                
                    });    
              }
            } 
        }
    }]);

这是一个工作 Plunker:http ://plnkr.co/edit/n20Sxq?p=preview

于 2013-10-21T19:54:31.497 回答
6

如果您不想自己处理链接逻辑,或者您想要隔离范围,我认为这更简单:

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
        return {
            scope: {
                template: '@template'
            },
            template: "<div ng-include='template'></div>"
        };
    }])

或者:

template:"<ng-include src='template'></ng-include>"
于 2014-09-09T19:56:22.693 回答
1

这是一篇旧帖子,但我认为如果有人来到这里寻求答案,它会很有用。

您可以尝试@caub 在评论中提到的 templateUrl 函数。同样也可以用于组件。

.directive("cellItem", ["$compile", '$http', '$templateCache', '$parse', function ($compile, $http, $templateCache, $parse) {
    return {
        templateUrl: function(element, attrs) {
           return attrs.template || 'someDefaultFallback.html';
        }
    };
}]);

我们在这里不需要任何注入的依赖项。希望这可以帮助某人。

于 2016-10-14T21:22:21.720 回答