TranscLlusion and Scopes in Angular: perché non funziona?
-
21-12-2019 - |
Domanda
Ho una configurazione molto semplice:
<pane title="mytitle">Title in parent (transcluded): {{title}}</pane>
.
e
angular.module('transclude', [])
.directive('pane', function(){
return {
restrict: 'E',
transclude: true,
scope: { title:'@' },
template: '<div>' +
'<div>Title in isolated scope: {{title}}</div>' +
'<div ng-transclude></div>' +
'</div>'
};
});
.
Il pinkeer è qui: http://plnkr.co/edit/yhcngjqaq1nhdtuwxku
La transclusione stessa funziona ma il {{title}}
viene sostituito solo nel modello della direttiva.
Il {{title}}
all'interno dell'elemento transcluso, tuttavia, rimane vuoto anche se la direttiva ha un title
variabile nella sua portata.Perché è così?
Soluzione
L'ambito dell'elemento transcluso non è una portata del bambino della direttiva, ma un fratello.Questo è ciò che dice la documentazione:
.In una tipica configurazione il widget crea un ambito dell'isolato, ma la transclusione non è un bambino, ma un fratello dell'ambito dell'isolato.
La soluzione più semplice in questo caso come è possibile accedere a Scope transscudato è come questa:
.directive('pane', function () {
return {
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
template:
'<div>' +
'<div>Title in isolated scope: {{title}}</div>' +
'<div ng-transclude></div>' +
'</div>',
link: function (scope, element, attrs) {
scope.$$nextSibling.title = attrs.title;
}
};
});
.
demo: http://plnkr.co/edit/ouq9b4f2qfph557708q1?p=preview
Altri suggerimenti
@DFSQ è corretto su:
.lo scopo dell'elemento transcluded non è una portata del bambino del Direttiva ma un fratellolo
Mi piacerebbe aggiungere altri commenti Perché questo è il comportamento previsto di Angularjs. Come dice i Documenti:
.In una tipica configurazione il widget crea un'ambito dell'isolato, ma il La trasmissione non è un bambino, ma un fratello dell'ambito dell'isolato. Questo rende possibile per il widget avere uno stato privato e il Transclux per essere vincolato alla portata principale (preisolate).
Il contenuto transsclato all'interno della direttiva è arbitrario, IT non dovrebbe Avere conoscenza della portata dell'isolato della direttiva, altrimenti, creeremmo un codice di accoppiamento aderente . Perché per il contenuto transsclato da lavorare, il contenuto deve conoscere i dettagli di implementazione della tua direttiva (cosa è disponibile per l'uso).
Se si decide che il contenuto appartiene alla direttiva. Hai 2 opzioni:
1) Fai la parte del contenuto del modello
angular.module('transclude', [])
.directive('pane', function(){
return {
restrict: 'E',
transclude: true,
scope: { title:'@' },
template: '<div>' +
'<div>Title in isolated scope: {{title}}</div>' +
'<div>' +
' Title in parent (transcluded): {{title}} ' +
' </div>' +
'</div>'
};
});
.
2) Utilizzare la tranclusione personalizzata per legare l'ambito di applicazione:
angular.module('transclude', [])
.directive('pane', function(){
return {
restrict: 'E',
transclude: true,
scope: { title:'@' },
template: '<div>' +
'<div>Title in isolated scope: {{title}}</div>' +
'<div class="transclude"></div>' +
'</div>',
link: function (scope, element, attr,controller, linker) {
linker(scope, function(clone){
element.find(".transclude").append(clone); // add to DOM
});
}
};
});
.