Komponenten ohne Beobachter schreiben
In dieser Antwort werden fünf Techniken beschrieben, mit denen AngularJS 1.5-Komponenten ohne Verwendung von Watchern geschrieben werden können.
Verwenden Sie die ng-change
Richtlinie
Welche alternativen Methoden stehen zur Verfügung, um Änderungen des Objektzustands zu beobachten, ohne watch zur Vorbereitung auf AngularJs2 zu verwenden?
Mit der ng-change
Direktive können Sie auf Eingabeänderungen reagieren.
<textarea ng-model='game.game'
ng-change="game.textChange(game.game)">
</textarea>
Um das Ereignis an eine übergeordnete Komponente weiterzugeben, muss der Ereignishandler als Attribut der untergeordneten Komponente hinzugefügt werden.
<game game='myBox.game' game-change='myBox.gameChange($value)'></game>
JS
app.component("game", {
bindings: {game:'=',
gameChange: '&'},
controller: function() {
var game = this;
game.textChange = function (value) {
game.gameChange({$value: value});
});
},
controllerAs: 'game',
templateUrl: "/template2"
});
Und in der übergeordneten Komponente:
myBox.gameChange = function(newValue) {
console.log(newValue);
});
Dies ist die bevorzugte Methode für die Zukunft. Die AngularJS-Strategie $watch
ist nicht skalierbar, da es sich um eine Abfragestrategie handelt. Wenn die Anzahl der $watch
Hörer etwa 2000 erreicht, wird die Benutzeroberfläche träge. Die Strategie in Angular 2 besteht darin, das Framework reaktiver zu gestalten und das Anbringen $watch
zu vermeiden $scope
.
Verwenden Sie den $onChanges
Lebenszyklus-Haken
Mit Version 1.5.3 hat AngularJS $onChanges
dem $compile
Service den Life-Cycle-Hook hinzugefügt .
Aus den Dokumenten:
Die Steuerung kann die folgenden Methoden bereitstellen, die als Lebenszyklus-Hooks fungieren:
- $ onChanges (changesObj) - Wird aufgerufen, wenn Einweg- (
<
) oder Interpolationsbindungen ( @
) aktualisiert werden. Dies changesObj
ist ein Hash, dessen Schlüssel die Namen der gebundenen Eigenschaften sind, die sich geändert haben, und deren Werte ein Objekt des Formulars sind { currentValue: ..., previousValue: ... }
. Verwenden Sie diesen Hook, um Aktualisierungen innerhalb einer Komponente auszulösen, z. B. das Klonen des gebundenen Werts, um eine versehentliche Mutation des äußeren Werts zu verhindern.
- AngularJS Comprehensive Directive API-Referenz - Life-Cycle-Hooks
Der $onChanges
Haken wird verwendet, um auf externe Änderungen an der Komponente mit <
Einwegbindungen zu reagieren . Die ng-change
Direktive wird verwendet, um Änderungen von der ng-model
Steuerung außerhalb der Komponente mit &
Bindungen zu propagieren .
Verwenden Sie den $doCheck
Lebenszyklus-Haken
Mit Version 1.5.8 hat AngularJS $doCheck
dem $compile
Service den Life-Cycle-Hook hinzugefügt .
Aus den Dokumenten:
Die Steuerung kann die folgenden Methoden bereitstellen, die als Lebenszyklus-Hooks fungieren:
$doCheck()
- Wird bei jeder Umdrehung des Verdauungszyklus aufgerufen. Bietet die Möglichkeit, Änderungen zu erkennen und darauf zu reagieren. Alle Aktionen, die Sie als Reaktion auf die von Ihnen erkannten Änderungen ausführen möchten, müssen über diesen Hook aufgerufen werden. Die Implementierung hat keine Auswirkung darauf, wann $onChanges
aufgerufen wird. Dieser Hook kann beispielsweise nützlich sein, wenn Sie eine gründliche Gleichheitsprüfung durchführen oder ein Datumsobjekt prüfen möchten, dessen Änderungen vom Änderungsdetektor von Angular nicht erkannt und somit nicht ausgelöst werden $onChanges
. Dieser Hook wird ohne Argumente aufgerufen. Wenn Sie Änderungen erkennen, müssen Sie die vorherigen Werte zum Vergleich mit den aktuellen Werten speichern.
- AngularJS Comprehensive Directive API-Referenz - Life-Cycle-Hooks
Intercomponent Kommunikation mit require
Direktiven können erfordern, dass die Controller anderer Direktiven die Kommunikation untereinander ermöglichen. Dies kann in einer Komponente erreicht werden, indem eine Objektzuordnung für die Eigenschaft require bereitgestellt wird . Die Objektschlüssel geben die Eigenschaftsnamen an, unter denen die erforderlichen Controller (Objektwerte) an den Controller der erforderlichen Komponente gebunden werden.
app.component('myPane', {
transclude: true,
require: {
tabsCtrl: '^myTabs'
},
bindings: {
title: '@'
},
controller: function() {
this.$onInit = function() {
this.tabsCtrl.addPane(this);
console.log(this);
};
},
templateUrl: 'my-pane.html'
});
Weitere Informationen finden Sie im AngularJS Developer Guide - Intercomponent Communicatation
Push-Werte von einem Service mit RxJS
Was ist mit einer Situation, in der Sie beispielsweise einen Dienst haben, der den Status "Halten" hat? Wie kann ich Änderungen an diesem Service vornehmen, und andere zufällige Komponenten auf der Seite können sich einer solchen Änderung bewusst sein? Ich hatte in letzter Zeit Probleme, dieses Problem anzugehen
Erstellen Sie einen Dienst mit RxJS-Erweiterungen für Angular .
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);
app.factory("DataService", function(rx) {
var subject = new rx.Subject();
var data = "Initial";
return {
set: function set(d){
data = d;
subject.onNext(d);
},
get: function get() {
return data;
},
subscribe: function (o) {
return subject.subscribe(o);
}
};
});
Dann abonnieren Sie einfach die Änderungen.
app.controller('displayCtrl', function(DataService) {
var $ctrl = this;
$ctrl.data = DataService.get();
var subscription = DataService.subscribe(function onNext(d) {
$ctrl.data = d;
});
this.$onDestroy = function() {
subscription.dispose();
};
});
Kunden können Änderungen mit abonnieren DataService.subscribe
und Produzenten können Änderungen mit vorantreiben DataService.set
.
Die DEMO auf PLNKR .