Signals
Signals
Signals sind etwas Ähnliches wie Observable von RxJs. Es ist ein Wrapper um einen Wert, welcher Konsumenten benachrichtigen kann, wenn sich der Wert ändert. Signals gibt es als Read-Only oder als Writable. Der Wert eines Signals wird immer durch eine getter-function gelesen. Wenn man ein Signal aufruft, wird der Wert darin gelesen. Man kann in Signals von primitiven bis hin zu komplexen Datenstrukturen wrappen
Writable Signals
Ein writable Signal kann ganz simple erstellt werden, in dem man die signal()
funktion aufruft mit dem initialen Wert.
|
|
Wenn man den gesamten Wert unabhängig vom momentanen ändern möchte, kann man .set()
aufrufen.
|
|
Möchte man jedoch mithilfe des momentanen Wertes was machen möchte, muss man .update()
aufrufen.
|
|
Die Variabel count
hat automatisch den Type WritableSignal
.
Computed signals (Read-Only)
Ein Computed Signal erhält seinen Wert von einem andern Signal, meist ein Writable Signal. Möchte man ein Computed Signal erstellen so die computed()
Funktion verwenden.
|
|
Bei einem Computed Signal kann man nicht direkt einen wert mit .set()
setzen wie bei den Writable. Es wird einen Compilation Error geben.
lazily evaluated and memoized
Der Wert des Computed Signals wird so lange nicht berechnet bis man es aufruft, danach wird der Wert gecached. Wenn man nun den Wert des Computed Signals erneut liest, wird es nicht neu berechnet, sondern nimmt den Wert aus dem Cache. Wenn man jedoch das Writable Signal, welches im Computed Signal verwendet wird ändert, weiss angular das der Wert im Cache für das Computed Signal nicht mehr valid ist. Somit wird der Wert neu berechnet wenn man das Computed Signal das nächste Mal aufruft und wieder gespeichert.
Computed signal dependencies are dynamic
Es werden nur die Signals getracked, die während der Ableitung auch gelesen werden.
Zum Beispiel wird im folgenden Beispiel das Signal “count” nur gelesen, wenn das Signal “showCount” wahr ist
|
|
Beim Lesen von conditionalCount
wird, wenn showCount
false
ist, die Nachricht “Hier gibt es nichts zu sehen!” zurückgegeben, ohne das Signal count
zu lesen.
Das bedeutet, dass eine spätere Aktualisierung von count
nicht dazu führt, dass conditionalCount
neu berechnet wird.
Wenn showCount
auf true
setzen und dann erneut conditionalCount
lesen, wird die Ableitung erneut ausgeführt und der Zweig ausgeführt, in dem showCount
wahr ist.
Es wird die Nachricht zurückgegeben, die den Wert von count
anzeigt. Eine Änderung von count
würde dann den zwischengespeicherten Wert von `conditionalCount ungültig machen.
Zu beachten ist, dass dependencies während einer Ableitung sowohl hinzugefügt als auch entfernt werden können. Wenn showCount
später wieder auf false
gesetzen wird, wird count
nicht mehr als dependencies von conditionalCount
betrachtet.
Effects
Signals sind ein interessanter Aspekt in Angular, da sie consumers benachrichtigen, wenn sie sich ändern. Der effect
ist eine Operation, welche ausgeführt wird sobald ein oder mehrere Werte eines Signals ändern.
effect
werden folgendermassen erstellt:
|
|
effect
werden im minimum immer einmal ausgeführt. Wenn ein effect
ausgeführt wird, verfolgt er alle gelesenen Werte des Signals. Immer wenn sich einer dieser Werte ändert, wird der effect
erneut ausgeführt.
Ähnlich wie bei computed signal verfolgen effect
ihre dependencies dynamisch und erfassen nur Signals, die in der aktuellsten Ausführung gelesen wurden.
effect
werden immer asynchron während des change detection process ausgeführt.
effect
werden in den meisten Anwendungsfällen selten benötigt, können jedoch in speziellen Situationen nützlich sein.
Hier sind einige Beispiele von Situationen, in denen ein effect
eine gute Lösung sein könnte:
- Logging von angezeigten Daten und deren Änderungen, entweder für Analysezwecke oder als Debugging-Tool.
- Synchronisierung von Daten mit
window.localStorage
. - Hinzufügen von benutzerdefiniertem DOM-Verhalten, das nicht mit der Template-Syntax ausgedrückt werden kann.
- Durchführung von benutzerdefinierter rendering auf einem
<canvas>
, in einer Diagrammbibliothek oder einer anderen UI-library von Drittanbietern.
Advanced topics
Signal equality functions
Wenn man ein Signal (egal ob Writable oder computed) erstellt, kann man optional eine equality function
angeben. Diese wird verwendet um zu prüfen, ob ein neuer Wert sich zum vorherigen unterscheidet.
|
|
Reading without tracking dependencies
Vereinzelt ist es erforderlich, Code auszuführen, der möglicherweise Signale innerhalb einer reaktiven Funktion wie computed
oder effect
liest, ohne eine dependency zu erstellen.
Beispielsweise, nehmen wir an, dass bei einer Änderung von currentUser
der Wert eines counter
protokolliert werden soll. Es kann ein Effekt erstellen werden, der beide Signale liest:
|
|
Dieses Beispiel gibt eine Meldung aus, wenn sich entweder currentUser
oder counter
ändert.
Wenn der Effekt jedoch nur dann ausgeführt werden soll, wenn sich currentUser
ändert, ist das Lesen von counter
nur zufällig, und Änderungen an counter
sollten keine neue Meldung protokollieren.
Man kann verhindern, dass ein Signal-Lesen verfolgt wird, indem man seinen Getter mit `untracked aufrufen:
|
|
untracked
ist auch nützlich, wenn ein Effekt externen Code aufrufen muss, der nicht als dependency behandelt werden soll:
|
|
Effect cleanup functions
Effekte können lang laufende Operationen starten, die abgebrochen werden sollten, wenn der Effekt zerstört wird oder bevor die erste Operation abgeschlossen ist und der Effekt erneut gestartet wird.
Wenn man einen Effekt erstellt, kann die Funktion optional eine onCleanup
-Funktion als ihren ersten Parameter akzeptieren.
Diese onCleanup
-Funktion ermöglicht es, einen callback zu registrieren, welcher aufgerufen wird, bevor der nächste Durchlauf des Effekts beginnt oder wenn der Effekt zerstört wird.
|
|