Here是我的剧本:
angular.module('MyApp',[])
.directive('mySalutation',function(){
return {
restrict:'E',
scope:true,
replace:true,
transclude:true,
template:'<div>Hello<div ng-transclude></div></div>',
link:function($scope,$element,$attrs){
}
};
})
.controller('SalutationController',['$scope',function($scope){
$scope.target = "StackOverflow";
}])
和html:
<body ng-app="MyApp">
<my-salutation ng-controller="SalutationController">
<strong>{{target}}</strong>
</my-salutation>
</body>
问题是,当SalutationController
指令应用my-salutation
时,$scope.target
对于已转换的元素不可见。但是如果我放ng-controller
在<body>
或<strong>
元素上,它有效。正如docs所说,ng-controller
创造了新范围。
谁可以解释,在这种情况下,指令的范围和范围如何相互干扰?
如何将控制器置于指令上?任何提示将不胜感激。
答案 0 :(得分:9)
1)问题是ng-transclude
的范围是指令的兄弟范围。将ng-controller
放入父元素时,ng-controller
创建的范围是指令和ng-transclude
的父范围。由于范围继承,transcluded元素能够正确绑定{{target}}
。
2)你可以使用自定义转换来自己绑定范围
.directive('mySalutation',function(){
return {
restrict:'E',
scope:true,
replace:true,
transclude:true,
template:'<div>Hello<div class="transclude"></div></div>',
compile: function (element, attr, linker) {
return function (scope, element, attr) {
linker(scope, function(clone){
element.find(".transclude").append(clone); // add to DOM
});
};
}
};
})
或者在链接功能中使用transclude功能:
.directive('mySalutation',function(){
return {
restrict:'E',
scope:true,
replace:true,
transclude:true,
template:'<div>Hello<div class="transclude"></div></div>',
link: function (scope, element, attr,controller, linker) {
linker(scope, function(clone){
element.find(".transclude").append(clone); // add to DOM
});
}
};
})
答案 1 :(得分:2)
要使指令和控制器具有相同的范围,您可以手动调用transcludeFn:
angular.module('MyApp',[])
.directive('mySalutation',function(){
return {
restrict:'E',
scope:true,
replace:true,
transclude:true,
template:'<div>Hello<div class="trans"></div></div>',
link:function(scope, tElement, iAttrs, controller, transcludeFn){
console.log(scope.$id);
transcludeFn(scope, function cloneConnectFn(cElement) {
tElement.after(cElement);
});
}
};
})
.controller('SalutationController',['$scope',function($scope){
console.log($scope.$id);
$scope.target = "StackOverflow";
}]);
您可以看到每次都会注销“003”,并且您的代码会按照预期进行微调。