Transklusion und Bereiche im Winkel:Warum funktioniert das nicht?
-
21-12-2019 - |
Frage
Ich habe ein sehr einfaches Setup:
<pane title="mytitle">Title in parent (transcluded): {{title}}</pane>
Und
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>'
};
});
Der Plunker ist hier: http://plnkr.co/edit/yRHcNGjQAq1NHDTuwXku
Die Transklusion selbst funktioniert, aber die {{title}}
wird nur in der Vorlage der Direktive ersetzt.
Der {{title}}
innerhalb des transkludierten Elements bleibt jedoch leer, obwohl die Direktive eine Variable enthält title
in seinem Umfang.Warum das?
Lösung
Der Geltungsbereich des transkludierten Elements ist kein untergeordneter Geltungsbereich der Richtlinie, sondern ein gleichgeordneter Geltungsbereich.Dies ist, was die Dokumentation sagt:
In einem typischen Setup erstellt das Widget einen isolierten Bereich, aber die Transklusion ist kein untergeordnetes Element, sondern ein Geschwister des isolierten Bereichs.
Die einfachste Lösung in diesem Fall, wie Sie auf den transkubierten Bereich zugreifen können, ist folgende:
.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
Andere Tipps
@dfsq hat Recht in Bezug auf:
Der Umfang des transkludierten Elements ist kein Kinderumfang der Richtlinie, sondern ein Geschwister
Ich möchte weitere Kommentare hinzufügen, warum dies das erwartete Verhalten von AngularJs ist.Wie die Dokumente sagen:
In einem typischen Setup erzeugt das Widget ein Isolatbereich, aber die Transklusion ist kein Kind, sondern ein Geschwister des Isolatsbereichs.Dies ermöglicht es dem Widget, einen privaten Zustand zu haben, und die Transklusion, um an den übergeordneten (vor-isolierten) Bereich gebunden zu werden.
Der transkludierte Inhalt innerhalb der Richtlinie ist willkürlich sollte nicht Kenntnisse über den isolierten Geltungsbereich der Richtlinie haben, andernfalls würden wir eine erstellen Code für enge Kopplung.Denn damit der transkludierte Inhalt funktioniert, muss der Inhalt die Implementierungsdetails Ihrer Direktive kennen (was zur Verwendung verfügbar ist).
Wenn Sie entscheiden, dass der Inhalt gehört zur Richtlinie.Sie haben 2 Möglichkeiten:
1) Machen Sie den Inhalt zu einem Teil der Vorlage
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) Verwenden Sie benutzerdefinierte Transklusion, um den Bereich selbst zu binden:
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
});
}
};
});