AngularJS
Winkelige $ -Optionen
Suche…
Bemerkungen
Angular verwendet einen Baum von Gültigkeitsbereichen, um die Logik (von Steuerungen, Anweisungen usw.) an die Ansicht zu binden und ist der Hauptmechanismus für die Änderungserkennung in AngularJS. Eine detailliertere Referenz für Bereiche finden Sie unter docs.angularjs.org
Die Wurzel des Baums ist über den injektierbaren Dienst $ rootScope zugänglich . Alle untergeordneten $ -Bereiche erben die Methoden und Eigenschaften ihres übergeordneten $ -Bereichs, sodass Kinder ohne Verwendung von Angular Services auf Methoden zugreifen können.
Grundlegendes Beispiel für die Vererbung von $ scope
angular.module('app', [])
.controller('myController', ['$scope', function($scope){
$scope.person = { name: 'John Doe' };
}]);
<div ng-app="app" ng-conroller="myController">
<input ng-model="person.name" />
<div ng-repeat="number in [0,1,2,3]">
{{person.name}} {{number}}
</div>
</div>
In diesem Beispiel erstellt die Direktive ng-repeat einen neuen Bereich für jedes der neu erstellten untergeordneten Elemente.
Diese erstellten Bereiche sind Kinder ihres übergeordneten Bereichs (in diesem Fall der von myController erstellte Bereich) und erben daher alle ihre Proportionen, z. B. person.
Vermeiden Sie das Erben primitiver Werte
In JavaScript einen nicht zuweisen primitiven Wertes (wie Objekt, Array, Funktion und viele mehr), hält eine Referenz (eine Adresse in dem Speicher) an den zugewiesenen Wert.
Durch das Zuweisen eines primitiven Werts (String, Number, Boolean oder Symbol) zu zwei verschiedenen Variablen und Ändern einer Variablen werden beide nicht geändert:
var x = 5;
var y = x;
y = 6;
console.log(y === x, x, y); //false, 5, 6
Da bei einem nicht primitiven Wert jedoch nur Verweise auf dasselbe Objekt beibehalten werden, ändert das Ändern einer Variablen die andere:
var x = { name : 'John Doe' };
var y = x;
y.name = 'Jhon';
console.log(x.name === y.name, x.name, y.name); //true, John, John
Wenn ein Bereich erstellt wird, werden ihm alle Eigenschaften des übergeordneten Objekts zugewiesen. Die nachträgliche Änderung der Eigenschaften wirkt sich jedoch nur auf den übergeordneten Bereich aus, wenn es sich um einen nicht primitiven Wert handelt:
angular.module('app', [])
.controller('myController', ['$scope', function($scope){
$scope.person = { name: 'John Doe' }; //non-primitive
$scope.name = 'Jhon Doe'; //primitive
}])
.controller('myController1', ['$scope', function($scope){}]);
<div ng-app="app" ng-controller="myController">
binding to input works: {{person.name}}<br/>
binding to input does not work: {{name}}<br/>
<div ng-controller="myController1">
<input ng-model="person.name" />
<input ng-model="name" />
</div>
</div>
Denken Sie daran: In Angular-Bereichen kann auf verschiedene Arten erstellt werden (z. B. eingebaute oder benutzerdefinierte Anweisungen oder die Funktion $scope.$new()
), und es ist möglicherweise unmöglich, den Gültigkeitsbereich zu verfolgen.
Wenn Sie nur nicht-primitive Werte als Bereichseigenschaften verwenden, bleiben Sie auf der sicheren Seite (es sei denn, Sie benötigen eine Eigenschaft, die nicht erbt, oder in anderen Fällen, in denen Sie die Vererbung des Bereichs kennen.).
Eine Funktion, die in der gesamten App verfügbar ist
Beachten Sie, dass dieser Ansatz möglicherweise als schlechtes Design für eckige Apps betrachtet wird, da Programmierer sich daran erinnern müssen, wo sich Funktionen in der Bereichsstruktur befinden, und dass die Vererbung des Bereichs bekannt ist. In vielen Fällen wäre es vorzuziehen, einen Dienst zu injizieren ( Angular-Praxis - Verwendung der Vererbung des Bereichs in Abhängigkeit von der Injektion) .
Dieses Beispiel zeigt nur, wie die Vererbung des Bereichs für unsere Anforderungen verwendet werden kann und wie Sie davon profitieren können, und nicht die bewährten Methoden zum Entwerfen einer gesamten App.
In einigen Fällen könnten wir die Vererbung des Bereichs nutzen und eine Funktion als Eigenschaft des rootScope festlegen. Auf diese Weise erben alle Bereiche in der App (mit Ausnahme von isolierten Bereichen) diese Funktion und können von überall in der App aufgerufen werden.
angular.module('app', [])
.run(['$rootScope', function($rootScope){
var messages = []
$rootScope.addMessage = function(msg){
messages.push(msg);
}
}]);
<div ng-app="app">
<a ng-click="addMessage('hello world!')">it could be accsessed from here</a>
<div ng-include="inner.html"></div>
</div>
inner.html:
<div>
<button ng-click="addMessage('page')">and from here to!</button>
</div>
Erstellen von benutzerdefinierten $ scope-Ereignissen
Wie bei normalen HTML-Elementen können $ scopes eigene Ereignisse haben. $ scope-Ereignisse können auf folgende Weise abonniert werden:
$scope.$on('my-event', function(event, args) {
console.log(args); // { custom: 'data' }
});
Wenn Sie die Registrierung eines Ereignis-Listeners aufheben müssen, gibt die $ on- Funktion eine unverbindliche Funktion zurück. Um mit dem obigen Beispiel fortzufahren:
var unregisterMyEvent = $scope.$on('my-event', function(event, args) {
console.log(args); // { custom: 'data' }
unregisterMyEvent();
});
Es gibt zwei Möglichkeiten , Ihre eigenen $ scope Ereignis $ Sendung auszulösen und $ emittieren. Verwenden Sie $ emit, um die Eltern über einen Bereich eines bestimmten Ereignisses zu informieren
$scope.$emit('my-event', { custom: 'data' });
Das obige Beispiel löst alle Ereignis-Listener für my-event
im übergeordneten Bereich aus und setzt die Gültigkeitsbereichsstruktur auf $ rootScope hoch, sofern nicht ein Listener stopPropagation
für das Ereignis stopPropagation
. Nur mit $ stopPropagation
ausgelöste Ereignisse können stopPropagation
Die Umkehrung von $ emit ist $ broadcast , wodurch alle Ereignis-Listener in allen untergeordneten Bereichen in der Bereichsstruktur ausgelöst werden, die untergeordnete Bereiche des Bereichs sind, der $ broadcast aufgerufen hat.
$scope.$broadcast('my-event', { custom: 'data' });
Mit $ broadcast ausgelöste Ereignisse können nicht abgebrochen werden.
$ Scope-Funktionen verwenden
Während die Deklaration einer Funktion im $ rootscope ihre Vorteile hat, können wir auch eine $ scope-Funktion an jedem Teil des Codes deklarieren, der vom $ scope-Service eingefügt wird. Controller zum Beispiel.
Regler
myApp.controller('myController', ['$scope', function($scope){
$scope.myFunction = function () {
alert("You are in myFunction!");
};
}]);
Jetzt können Sie Ihre Funktion vom Controller aus aufrufen:
$scope.myfunction();
Oder über HTML, das sich unter diesem speziellen Controller befindet:
<div ng-controller="myController">
<button ng-click="myFunction()"> Click me! </button>
</div>
Richtlinie
Eine Winkelanweisung ist ein weiterer Ort, an dem Sie Ihren Gültigkeitsbereich verwenden können:
myApp.directive('triggerFunction', function() {
return {
scope: {
triggerFunction: '&'
},
link: function(scope, element) {
element.bind('mouseover', function() {
scope.triggerFunction();
});
}
};
});
Und in Ihrem HTML-Code unter demselben Controller:
<div ng-controller="myController">
<button trigger-function="myFunction()"> Hover over me! </button>
</div>
Natürlich können Sie ngMouseover für dasselbe verwenden, aber das Besondere an Anweisungen ist, dass Sie sie nach Ihren Wünschen anpassen können. Und jetzt wissen Sie, wie Sie Ihre $ scope-Funktionen in ihnen einsetzen können, seien Sie kreativ!
Wie können Sie den Geltungsbereich einer Richtlinie einschränken und warum sollten Sie dies tun?
Der Bereich wird als "Klebstoff" verwendet, mit dem wir zwischen dem übergeordneten Controller, der Direktive und der Direktive-Vorlage kommunizieren. Bei jedem Bootstrapping der AngularJS-Anwendung wird ein RootScope-Objekt erstellt. Jeder durch Controller, Direktiven und Services erstellte Bereich wird prototypisch von rootScope übernommen.
Ja, wir können den Anwendungsbereich einer Richtlinie einschränken. Wir können dies tun, indem wir einen isolierten Geltungsbereich für die Richtlinie schaffen.
Es gibt drei Arten von Richtlinienbereichen:
- Geltungsbereich: Falsch (Richtlinie verwendet den übergeordneten Geltungsbereich)
- Geltungsbereich: Richtig (Richtlinie erhält einen neuen Geltungsbereich)
- Geltungsbereich: {} (Richtlinie erhält einen neuen isolierten Geltungsbereich)
Direktiven mit dem neuen isolierten Bereich: Wenn wir einen neuen isolierten Bereich erstellen, wird er nicht vom übergeordneten Bereich geerbt. Dieser neue Bereich wird als isolierter Bereich bezeichnet, da er vollständig vom übergeordneten Bereich getrennt ist. Warum? Verwenden Sie den isolierten Bereich: Wir sollten den isolierten Bereich verwenden, wenn Sie eine benutzerdefinierte Direktive erstellen möchten, da dadurch sichergestellt wird, dass unsere Direktive generisch ist und sich innerhalb der Anwendung befindet. Der übergeordnete Bereich wird den Richtlinienbereich nicht beeinträchtigen.
Beispiel für einen isolierten Umfang:
var app = angular.module("test",[]);
app.controller("Ctrl1",function($scope){
$scope.name = "Prateek";
$scope.reverseName = function(){
$scope.name = $scope.name.split('').reverse().join('');
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: {},
template: "<div>Your name is : {{name}}</div>"+
"Change your name : <input type='text' ng-model='name'/>"
};
});
Es gibt drei Arten von Präfixen, die AngularJS für den isolierten Umfang bereitstellt.
- "@" (Textbindung / Einwegbindung)
- "=" (Direkte Modellbindung / bidirektionale Bindung)
- "&" (Verhaltensbindung / Methodenbindung)
Alle diese Präfixe erhalten Daten von den Attributen des Direktive-Elements wie:
<div my-directive
class="directive"
name="{{name}}"
reverse="reverseName()"
color="color" >
</div>