如何通过属性中的scope变量传入templateUrl

时间:2022-08-24 12:21:04

I'm trying to pass in the url for the template via a scope variable. The scope will not change so the template doesn't need to update based on it, but currently the scope variable is always undefined.

我正在尝试通过范围变量传递模板的URL。范围不会更改,因此模板不需要基于它进行更新,但是当前范围变量始终未定义。

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

Ideally the directive would be:

理想情况下,指令将是:

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

This doesn't work however. I've tried a lot of different permutations in accomplishing the same concept, and this seems the closest, however it still doesn't work.

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

.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));
                });
            }
        };
    }])

I've also tried using ng-include, but that also doesn't evaluate scope variables before compiling. The CellTemplate value is coming from a database call so is completely unknown before evaluation. Any suggestions for getting this working would be greatly appreciated!

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

Edit: I'm using angular 1.0.8 and am not able to upgrade to a newer version.

编辑:我正在使用角度1.0.8,我无法升级到更新的版本。

3 个解决方案

#1


14  

You are not far off at all.

你离我不远。

You don't need to use an isolated scope for the directive. You can pass the templateUrl like this:

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

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

Then add a watch to detect when the template value changes:

然后添加一个监视以检测模板值何时更改:

.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));                
                    });    
              }
            } 
        }
    }]);

Here is a working Plunker: http://plnkr.co/edit/n20Sxq?p=preview

这是一个有效的Plunker:http://plnkr.co/edit/n20Sxq?p = preview

#2


6  

If you don't want to deal with the linking logic yourself, or you want the isolate scope, I think this is simpler:

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

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

or:

要么:

template:"<ng-include src='template'></ng-include>"

#3


1  

It's an old post but I thought its useful if anyone lands in here for the answer.

这是一个古老的帖子,但我认为如果有人在这里找到答案,它会很有用。

You can try the templateUrl function as @caub mentioned in a comment. Same can also be used for components.

您可以尝试将templateUrl函数作为注释中提到的@caub。同样也可以用于组件。

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

We don't need any of the injected dependencies here. Hope this helps someone.

我们不需要任何注入的依赖项。希望这有助于某人。

#1


14  

You are not far off at all.

你离我不远。

You don't need to use an isolated scope for the directive. You can pass the templateUrl like this:

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

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

Then add a watch to detect when the template value changes:

然后添加一个监视以检测模板值何时更改:

.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));                
                    });    
              }
            } 
        }
    }]);

Here is a working Plunker: http://plnkr.co/edit/n20Sxq?p=preview

这是一个有效的Plunker:http://plnkr.co/edit/n20Sxq?p = preview

#2


6  

If you don't want to deal with the linking logic yourself, or you want the isolate scope, I think this is simpler:

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

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

or:

要么:

template:"<ng-include src='template'></ng-include>"

#3


1  

It's an old post but I thought its useful if anyone lands in here for the answer.

这是一个古老的帖子,但我认为如果有人在这里找到答案,它会很有用。

You can try the templateUrl function as @caub mentioned in a comment. Same can also be used for components.

您可以尝试将templateUrl函数作为注释中提到的@caub。同样也可以用于组件。

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

We don't need any of the injected dependencies here. Hope this helps someone.

我们不需要任何注入的依赖项。希望这有助于某人。