AngularJS-Direktive – Scopes
Scopes in AngularJS-Direktiven
Ich möchte über AngularJS-Direktiven und verschiedene Arten von Scopes sprechen, die verwendet werden können. Es gibt 3 Hauptwege, auf denen Scopes von der aufrufenden Ansicht (HTML) an die Direktive übergeben werden können:
- Default Scope
- Inherited Scope
- Isolated Scope
Und der isolierte Scope könnte selbst sein:
- Oneway
- Twoway
- Methodenreferenz
Default Scope
Bei diesem Typ fließt der Scope aus der äußeren Sicht einfach in die Richtlinie ein. Anders ausgedrückt, der Bereich wird als „Referenz“ an die Richtlinie übergeben. Alle Daten des Bereichs sind in der Richtlinie sofort verfügbar und können verwendet werden. Ebenso wird jede Änderung des Bereichs innerhalb der Richtlinie sofort in der aufrufenden Ansicht reflektiert.
Dies wird erreicht, indem der Bereich als
scope: false // false is the default value
in der Richtliniendefinition angegeben wird.
Im folgenden Beispiel wird „name“ in die Richtlinie eingefügt und jede Änderung wird sofort nach außen übertragen. Da der Geltungsbereich auf true gesetzt ist, erhält die Direktive den Geltungsbereich als ihren Aufrufer. Jetzt wird jede Änderung des Namens in der Direktive sofort im ‚MyController‘ Controller reflektiert.
var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: false,
template: 'Name: <input ng-model="name"></input>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/830rn1fm/
Inherited Scope
In diesem Typ wird ein neuer Scope vom View Scope geerbt. In Javascript werden Objekte über prototypische Vererbung vererbt. Dieses Szenario ist im folgenden Diagramm dargestellt:
Dies wird erreicht, indem der Scope als
scope: true
in der Direktiven-Definition angegeben wird.
Im folgenden Beispiel können Sie versuchen, den Namen in der Direktive zu ändern. Diese Änderung wird aufgrund des „vererbten“ Geltungsbereichs nicht nach außen weitergegeben. Der Wert fließt nur innerhalb der Richtlinie, aber jede Änderung führt zu einer Kopie für die Richtlinie und wird nicht außerhalb reflektiert.
In dem Live-Beispiel unten können Sie sehen, dass der ‚Name‘ in die Richtlinie fließt; aber die Änderung in der Richtlinie wird nicht außerhalb reflektiert.
In dem Beispiel unten wird dem Geltungsbereich der Richtlinie ein Wert von true gegeben. Das bedeutet, dass ein Bereich für die Richtlinie erstellt wird, der vom Bereich des Controllers „erbt“. Gemäß den prototypischen Vererbungsregeln von Javascript bezieht sich das abgeleitete Objekt (Bereich der Direktive) auf die gleichen Eigenschaften des übergeordneten Objekts (Bereich des Controllers). Alle am Controller vorgenommenen Änderungen werden in der Direktive widergespiegelt, bis eine Änderung an der Eigenschaft „name“ in der Direktive vorgenommen wird. Zu diesem Zeitpunkt wird ein neues Objekt für die Richtlinie erstellt und die Änderungen sind undurchsichtig.
var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: true,
template: 'Name: <input ng-model="name"></input>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/57sb6yg8/
Isolated Scope
Bei dieser Art der Bereichsdefinition erhält die Richtlinie einen unabhängigen Bereich, der keine Daten empfängt oder an die enthaltende Ansicht zurücksendet.
Dies wird erreicht, indem der Bereich als
scope: {}
in der Definition der Richtlinie angegeben wird.
Im folgenden Beispiel wird der isolierte Geltungsbereich erreicht, indem ein leeres Objekt {} an die Direktive übergeben wird.
var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: {},
template: 'Name: <input ng-model="name"></input>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/7d37w08e/
Der isolierte Geltungsbereich ist wirklich mehr als die vollständige Einschränkung aller Daten, die in die Direktive (und aus ihr heraus) übergeben werden. An einem Ende des Spektrums können Sie die Daten vollständig einschränken, wie im obigen Beispiel gezeigt. Es ist aber auch möglich, ein oder mehrere Attribute an die Direktive zu übergeben und sie als Bereich für die Direktive zu erfassen. Die Flexibilität liegt in der Art und Weise, wie das übergebene Attribut innerhalb der Direktive interpretiert wird. Das an die Direktive übergebene Attribut kann auf eine der drei folgenden Arten interpretiert werden:
- als Einweg, der vor der Übergabe an die Direktive ausgewertet wird
- als Zweiweg ein Verweis auf eine Eigenschaft im aufrufenden Bereich
- als Verweis auf eine Methode im aufrufenden Bereich
Ausdruck
Der Aufrufer der Direktive kann explizit einen Wert übergeben, wie unten gezeigt:
<div my-directive name='{{name}}' />
// an expression is passed to the directive
Die Art und Weise, wie sie innerhalb der Direktive erfasst wird, ist:
scope: {
name: '@name'
}
Das Symbol@ weist Angular an, das Attribut name als Ausdruck zu betrachten und auszuwerten, bevor der Wert der Eigenschaft text zugewiesen wird. Da der Ausdruck ausgewertet wird, handelt es sich um eine einseitige Bindung, und jede Aktualisierung des Wertes innerhalb der Direktive wird nicht außerhalb reflektiert.
Im folgenden Beispiel sehen Sie, dass die Eigenschaft name an die Direktive übergeben wird. Dabei handelt es sich um einen Ausdruck, der ausgewertet und dem isolierten Geltungsbereich der Direktive zugewiesen wird. Das bedeutet, dass der Wert „Jack“ als Text innerhalb der Direktive ausgewertet und zugewiesen wird.
var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
});
// usage: <div my-directive name='{{name}}' />
myApp.directive('upperCase', function() {
return {
scope: {
name: '@name'
},
template: 'Name: <input ng-model="name"></input>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/ybzcryt0/4/
Da name ein Text in der Direktive ist, sind die Änderungen lokal in der Direktive und werden nicht an den übergeordneten Controller weitergegeben.
Zwei-Wege (Verweis auf eine Eigenschaft)
Der Aufrufer der Direktive kann einen Verweis auf eine Eigenschaft an die Direktive übergeben, wie in:
<div my-directive name='data.name' />
// a property reference to the directive
Die Art und Weise, wie es innerhalb der Direktive erfasst wird, ist:
scope: {
name: '=name'
}
= Symbol sagt Angular, dass es das name-Attribut als einen Verweis auf eine bestimmte Eigenschaft des aufrufenden Bereichs betrachtet. Der Wert wird also an die Direktive übergeben und jede Änderung des Attributs wird sofort nach außen reflektiert.
Im folgenden Beispiel sehen Sie, dass die Eigenschaft name an die Direktive übergeben wird. Dies ist ein Verweis auf die Eigenschaft name im übergeordneten Bereich.
var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
});
myApp.directive('upperCase', function() {
return {
scope: {
name: '=name'
},
template: 'Name: <input ng-model="name"></input>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/o74nvcj3/1/
Da name ein Verweis auf die Eigenschaft im Controller ist, werden alle Änderungen auf beiden Seiten reflektiert.
Referenz auf Methode
Die Art und Weise, wie es vom aufrufenden View übergeben wird, ist:
<div my-directive nameFn="getName()" />
// a method reference is passed to the directive
Die Art und Weise, wie es innerhalb der Direktive erfasst wird, ist:
scope: {
nameFn: '& nameFn'
}
&Das Symbol weist Angular an, das nameFn-Attribut als Referenz auf eine bestimmte Methode des aufrufenden Bereichs zu betrachten. Diese Methode kann dann bei Bedarf innerhalb der Direktive ausgeführt werden.
Im folgenden Beispiel ist die Eigenschaft nameFn eine Methode, deren Referenz innerhalb der Direktive übergeben wird. Diese Funktion wird von der Direktive ausgeführt, aber im Kontext des aufrufenden Bereichs ausgewertet.
var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
$scope.getName = function() {
return $scope.name;
}
});
myApp.directive('upperCase', function() {
return {
scope: {
nameCb: '&name'
},
//template: 'Name: <input ng-model="nameFn()"></input>'
template: 'Name: {{textCb()}}'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/6w4msr5k/1/
Zusammenfassung
Wie Sie sehen können, ist der Geltungsbereich der Direktive ziemlich erschöpfend, die folgende Zusammenfassung fasst die Möglichkeiten und ihre Bedeutung zusammen.
- Default : Die Direktive erhält den gleichen Geltungsbereich wie die sie enthaltende Ansicht
- Inherited: Richtlinie erhält einen Bereich, der vom Bereich der enthaltenden Ansicht geerbt wird
- Isoliert: Direktive erhält einen Bereich, der unabhängig von der enthaltenden View ist
Und innerhalb des isolierten Bereichs gibt es 3 Möglichkeiten:
Oneway : Das Attribut der Direktive wird als Ausdruck betrachtet und ausgewertet, bevor es einer bestimmten Eigenschaft des isolierten Bereichs der Direktive zugeordnet wird