当我们没有指定 scope:true(new Scope) 或 scope:{} (isolatedScope) 时,当我们重新使用该指令时,在作用域上定义的属性将被覆盖。
例如:
<div ng-controller="AppCtrl">
<my-control name="myControl1">
Some Content: {{value}}
My Control Name: {{name}}
</my-control>
<my-control name="myControl2">
Some Content: {{value}}
My Control Name: {{name}}
</my-control>
</div>
它不会在屏幕上同时打印myControl1 和myControl2,而是打印两次myControl2。
Plnkr
要解决此问题,请尝试以下任一解决方案。
解决方案1
transclde:true 将创建一个新的作用域。在这个范围而不是指令的范围上设置属性。
app.directive('myControl', function() {
return {
restrict: 'E',
transclude: true,
template: '<div><p><strong>Welcome to the testMe directive!</strong></p> <div ng-transclude></div></div>',
link: function(scope, element, attrs) {
var transclusionTarget = element[0].querySelector('[ng-transclude]').firstChild;
var transclusionScope = angular.element(transclusionTarget).scope();
transclusionScope.name = attrs.name;
}
}
});
这里ng-transclude div 下的元素将使用transclusionScope 进行编译,抓取它并更新其中的属性。
Plnkr
解决方案2
不要使用ng-transclude,而是手动嵌入内容。
app.directive('myControl', function() {
return {
restrict: 'E',
transclude: true,
template: '<div><p><strong>Welcome to the testMe directive!</strong></p> <div transclude-target></div></div>',
link: function(scope, element, attrs, directiveCtrl, transcludeFn ) {
var transclusionScope = scope.$new(),
transclusionTarget = element[0].querySelector('[transclude-target]');
transclusionScope.name = attrs.name;
transcludeFn(transclusionScope, function (clone) {
angular.element(transclusionTarget).append(clone);
});
}
}
});
在这里,创建一个new Scope 使用scope.$new() 扩展指令的范围。并更新其中的属性。
Plnkr
Solution1 可能并不适用于所有情况。当我们访问firstChild 时,如果它还没有准备好Solution1 将失败。
Solution2 更简洁,适用于所有情况。