AngularJS: ng-controller on directive nie działa na elementach transkludowanych w ramach dyrektywy
Tutaj jest mój skrypt:
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";
}])
I html:
<body ng-app="MyApp">
<my-salutation ng-controller="SalutationController">
<strong>{{target}}</strong>
</my-salutation>
</body>
Problem polega na tym, że gdy SalutationController
zostanie zastosowana do my-salutation
dyrektywy, $scope.target
nie jest widoczny dla elementu transkludowanego.Ale jeśli umieszczę ng-controller
na <body>
lub na <strong>
element, to działa. Jak mówi docs, ng-controller
tworzy nowy zakres.
Kto może wyjaśnić, w jaki sposób ten zakres i zakres dyrektywy zakłócają się wzajemnie w tym przypadku?
Jak mogę umieścić kontroler w sprawie dyrektywy? Wszelkie wskazówki będą mile widziane.
2 answers
1) problem polega na tym, że zakres ng-transclude
jest zakresem Twojej dyrektywy. Gdy umieścisz ng-controller
do elementu nadrzędnego, zakres utworzony przez ng-controller
jest nadrzędnym zakresem zarówno Twojej dyrektywy, jak i ng-transclude
. Ze względu na dziedziczenie zakresu, element transkludowany jest w stanie poprawnie powiązać {{target}}
.
2) możesz to zrobić za pomocą niestandardowej transcluzji, aby samodzielnie powiązać zakres
.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
});
};
}
};
})
Lub za pomocą funkcji transclude w linku funkcja:
.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
});
}
};
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-22 09:22:51
Aby mieć ten sam zakres dla dyrektywy i kontrolera, można wywołać trancludefn ręcznie:
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";
}]);
Możesz zobaczyć, że '003' jest wylogowany za każdym razem, a Twój kod działa zgodnie z oczekiwaniami z tą drobną korektą.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-22 09:16:40