角度指令不同模板

Mas*_*son 30 directive angularjs

我有一个带变量类型的指令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;
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

但不知道在哪里做.

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

Rob*_*b J 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';
                }
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅$ compile服务的文档.

  • 这是最简洁的答案,应该是公认的答案. (10认同)

Mar*_*cok 25

您可以使用内部解决此问题:ng-includecompile

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

小提琴


小智 7

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

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

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

我可以为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;
        }
    }
);
Run Code Online (Sandbox Code Playgroud)

我-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>
Run Code Online (Sandbox Code Playgroud)

我-directive.html


Joe*_*vey 5

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

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

例如,在指令上

<div my-directive custom-template="custom"></div>
Run Code Online (Sandbox Code Playgroud)