角度指令不同模板

时间:2013-05-10 20:33:14

标签: angularjs directive

我有一个变量类型的指令myDirective。如果我运行<my-directive type="X">,我希望该指令使用templateUrl:x-template.html。 如果我<my-directive type="Y">我希望该指令使用templateUrl:y-template.html。

这是我目前的指示。

app.directive('myDirective', function() {
    var myDirective = {
        templateUrl: 'X-template.html',
        restrict: 'E',
        scope: {
            type: '=' 
        },
    };
    return myDirective;
});

我通过stackoverflow和angular文档阅读但没有找到我需要的任何东西。

我现在正试图做一些事情:

if ($scope.type === 'X') {
    templateUrl: 'X-template.html',
}
else if ($scope.type === 'Y') {
    templateUrl: 'Y-template.html',
}

但不知道该怎么做。

你们知道这是否可行以及如何实现?

6 个答案:

答案 0 :(得分:102)

Angular会接受一个函数作为模板选项,所以你可以这样做:

.directive('myDirective', function () {
    return {
        templateUrl: function (tElement, tAttrs) {
            if (tAttrs) {
                if (tAttrs.type === 'X') {
                    return 'X-template.html';
                }
                if (tAttrs.type === 'Y') {
                    return 'Y-template.html';
                }
            }
        }
    }
});

有关详细信息,请参阅$compile服务的文档。

答案 1 :(得分:25)

您可以使用ng-include内的compile处理this issue

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        compile: function(element, attrs) {
            element.append('<div ng-include="\'' + attrs.type + '-template.html\'"></div>');
        }
    }
});

fiddle

答案 2 :(得分:6)

如果你愿意生活在1.1.x代码路径上的前沿(请注意每个1.1.x构建注释条目附带的警告,所以我不会在这里再次重复它来淡化这个答案),你很幸运 - 这个特性刚刚在4月3日的1.1.4版本中添加。您可以找到1.1.4 here的发行说明,该功能的task log包含一个演示如何使用新功能的Jasmine测试。

如果你更保守并且正在使用1.0.x版本,那么你将无法轻松实现这一目标,但它可以完成。 Mark Rajcok的解决方案看起来符合您的要求,但我只想添加一些注意事项:

  • 除了1.1.4版本之外,编译时指令不支持在运行时进行修改。
  • 您可能需要考虑replaceWith()而不是append(),因为<my-directive>不是标准定义的HTML元素类型。
  • 如果您的X和Y模板包含其他指令,我认为您无法轻松地将<my-template>上的属性传递到模板的根元素。
    • 使用replace:true的指令会将属性从源元素传输到其替换根,但我不认为ngInclude将从包含模板的根目录的主机执行相同操作。
    • 我似乎也记得ngInclude并不要求其模板只有一个根元素。
    • 您可以使用replaceWith()代替append()并将<div ng-include="">标记包含在<div></div>中,以保留替换父级的属性。外部<div>可以包含属性,并且在<div ngInclude>元素替换为已加载内容后仍可访问。
  • 请注意ngInclude创建新范围。这将使您听到关于原始示波器模型的危险性的闪烁黄色卡拉OK警告。有关详细信息,请参阅this fine page from Angular's GitHub depot

我可以为1.0.x上的那些提出另一种选择,但它涉及相当多的代码。这是一个更重量级的操作,但它具有不仅能够在模板之间切换,而且还具有完整指令的优点。此外,它的行为更容易动态。

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: 'partials/directive/my-directive.html',
        link: function(scope, element, attrs, ctrl) {
            // You can do this with isolated scope as well of course.
            scope.type = attrs.type;
        }
    }
);

MY-directive.js

<div ng-switch on="{{type}}">
    <div ng-switch-where="X" ng-include="X-template.html"></div>
    <div ng-switch-where="Y" ng-include="Y-template.html"></div>
</div>

MY-directive.html

答案 3 :(得分:5)

这是我的版本,可选择覆盖默认模板

templateUrl: function (elem, attrs) {
  if (attrs.customTemplate) {
    return '/path/to/components/tmpl/' + attrs.customTemplate + '.html';
  } else {
    return '/path/to/components/tmpl/directive.html';
  }
}

例如在指令

<div my-directive custom-template="custom"></div>

答案 4 :(得分:4)

我解决了这个问题:

app.directive("post", function ($templateCache, $compile) {
function getTemplate(mode) {
    switch (mode) {
        case "create":
            return "createPost.html";
        case "view":
            return "viewPost.html";
        case "delete":
            return "deletePost.html";
    }
}

var defaultMode = "view";

return {
    scope: {},
    restrict: "AE",
    compile: function (elem, attrs, transclude) {
        return function ($scope, $element, $attr) {
            function updateTemplate() {
                $element.html("");
                $compile($templateCache.get(getTemplate($scope.mode)).trim())($scope, function (clonedElement, scope) {
                    clonedElement.appendTo($element);

                });
            }

            $scope.mode = $attr.mode || defaultMode;

            $scope.$watch("mode", updateTemplate);
        }
    }
}
});

这可能不是最好的方法,但我没有额外的范围。

答案 5 :(得分:-1)

好的,这可能对这里有人有帮助: - )

要将自定义attr注入链接或控制器功能,请使用以下命令。

我现在正在上班,但如果有机会,我会稍后发布一个小提琴: - )

.directive('yourDirective', function() {
  return {
    restrict: 'EA',
    template: '<div></div>', // or use templateUrl with/without function
    scope: {
      myAttibute: '@myAttr' // adds myAttribute to the scope
    },
    link: function(scope) {
      console.log(scope.myAttibute);
    }
  }
}

// HTML&#34;&#34;

//控制台将输出&#34; foo&#34;