据我所知,我可以根据选项DOM属性template-url="foo.html"
动态设置templateUrl,给出以下代码:
angular.module('foo').directive('parent', function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
// code
},
templateUrl: function(elem,attrs) {
return attrs.templateUrl || 'some/path/default.html'
}
}
});
但是,我需要更进一步,将这个字符串更深一层地传递给子指令。
鉴于此HTML:
主项目中的用法
<parent parent-template="bar.html" child-template="foo.html"></parent>
在大多数情况下,子项不会公开,因此如果设置了child-template
,则需要隐式替换位于父templateUrl
中的所有子<child></child>
元素foo.html
1}}。
require: '^parent'
属性将数据从范围传递到范围,但我在templateUrl
声明时没有看到它。
foo.html
<h1>Title</h1>
<child ng-repeat="item in array"></child>
指令
angular.module('foo').directive('parent', function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
// code
},
templateUrl: function(elem,attrs) {
return attrs.parentTemplate || 'some/path/default.html'
},
scope: {
childTemplate: '=childTemplate'
}
}
})
.directive('child', function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
// code
},
templateUrl: function(elem,attrs) {
return ??? // parent.attribute.childTemplate? || 'some/path/default.html'
},
require: '^parent',
scope: {
childTemplate: '=childTemplate'
}
}
});
答案 0 :(得分:1)
旧的答案(见下文)不起作用,因为它只能访问link
函数内所需指令的控制器,templateUrl
函数得到在link
函数之前执行。
因此,解决此问题的唯一方法是处理子指令的templateUrl
函数中的所有内容。但是this function only takes 2 arguments: tElement
and tArgs
。
因此,我们必须找到父指令的元素并访问属性child-template
。像这样:
angular.module('testApp', [])
.directive('parent', function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
},
transclude:true,
templateUrl: function(elem,attrs) {
return attrs.parentTemplate || 'default.html'
}
}
})
.directive('child', function() {
return {
restrict: 'E',
require:'^parent',
templateUrl: function(elem,attrs) {
//if jQuery is loaded the elem will be a jQuery element, so we can use the function "closest"
if(elem.closest)
return elem.closest("parent").attr("child-template") || 'default.html';
//if jQuery isn't loaded we will have to do it manually
var parentDirectiveElem=elem;
do{
parentDirectiveElem=parentDirectiveElem.parent();
}while(parentDirectiveElem.length>0 && parentDirectiveElem[0].tagName.toUpperCase()!="PARENT");
return parentDirectiveElem.attr("child-template") || 'default.html';
}
}
});
由于你正在隔离范围,你可以试试这个,它有点hacky但我想它应该有效:
angular.module('foo').directive('parent', function() {
return {
restrict: 'E',
controller: function($scope) {
this.childTemplate=$scope.childTemplate;
},
link: function(scope, element, attrs) {
},
templateUrl: function(elem,attrs) {
return attrs.parentTemplate || 'some/path/default.html'
},
scope: {
childTemplate: '@'
}
}
})
.directive('child', function() {
return {
restrict: 'E',
require: '^parent',
link: function(scope, element, attrs, parentController) {
if(parentController.childTemplate)
element.data("childTemplate", parentController.childTemplate);
},
templateUrl: function(elem,attrs) {
return elem.data("childTemplate") || 'some/path/default.html'
}
}
});
答案 1 :(得分:0)
在我的问题中,我试图为没有一个现成指令的templateUrl
提供覆盖。我原来的问题没有提到这一点,但是,我想把这个作为对我可能已经忘记的其他人的参考。 Angular允许您修饰指令并覆盖它们的属性。
app.config(function($provide) {
$provide.decorator('child', function($delegate) {
var directive = $delegate[0];
directive.templateUrl = 'path/to/custom.html';
return $delegate;
});
});