Observable

Wie lässt sich ein Wert nach dessen Änderung z.B. auf mehreren Textfeldern synchronisiert darstellen?

In vielen Programmiersprachen bietet sich hierfür das Entwurfsmuster 'Observer-Pattern' an, dass in verschiedenen Sprachen sehr unterschiedlich implementiert wurde. Das Prinzip gestaltet sich allerdings gleich: Der 'Erzähler' (Observable) hält Informationen bereit an die sich 'Zuhörer' (Listener) registrieren können. Sobald der 'Erzähler' neue Informationen bekommt, benachrichtigt er seine 'Zuhörer'.

Beispiel

Listener erstellen

Als erstes wird ein Listener erstellt. Ein Listener ist ein Schlüssel-Wert Paar, dessen Wert eine Funktion ist, die bei einer Wertänderung auf dem Observable, aufgerufen wird. Somit kann mit dieser Funktion auf eine Wertänderung reagiert werden. Diese Funktion nimmt zwei Parameter entgegen, als erstes dennewValue und als zweites den oldValue.

In diesem Beispiel wird die Variable listenerVariable immer mit dem newValue-Wert überschrieben, wenn der Listener vom Observable über eine Wertänderung benachrichtigt wird. oldValue wird in diesem Beispiel nicht verwendet.

let listenerVariable; // undefined
const listenerExample = newListener( newValue => oldValue  => listenerVariable = newValue );

Observable erstellen und Listener registrieren

Nachdem ein 'Zuhörer' (Listener) erstellt wurde, braucht es noch den 'Erzähler' (Observable). Dafür gibt es die Funktion Observable welche als ersten Parameter den initialen Wert entgegennimmt. Mit der Funktion addListener wird der zuvor erstellte Listener registriert.

let obsExample = Observable(42)                     // new Observable with initValue 42
                  (addListener)( listenerExample ); // append Listener to the Observable
circle-info

Nachdem einer Listener mit einem Observable verknüpft ist, erhält der Listener sofort den aktuellsten Stand (initialen Wert) vom Observable. In diesem Beispiel die Zahl '42'.

listenerVariable   // 42

Aktueller Wert abfragen

Die Funktion getValue gibt den aktuellen Wert aus dem Observable zurück.

Wertänderung

Mit der Funktion setValue wird dem Observable ein neuer Wert mitgeteilt. Alle verbundene Listener werden benachrichtig und der neue Wert als newValue __mitgegeben. Der vorherige Wert als oldValue. Die Funktion setValue gibt ein neues Observable zurück.

Listener entfernen

Wenn ein Listener wieder von einem Observable entfernt werden soll, gibt es dafür die FunktionremoveListener. Diese Funktion gibt wieder ein Observable zurück.

Der zuvor entfernte Listener bekommt nun keine Wertänderungen mehr mit.

Zusammenfassung:

Observable Text-Input Beispiel

In diesem Beispiel-Projekt gibt es ein 'Observable', welches auf die Wertänderungen eines Text-Input-Feldes auf dem UI reagiert. Dabei werden alle 'Listener' mit dem neuen und alten Wert informiert.

circle-info

In der Demo sind die Checkboxen neben den Labels zum entfernen und hinzufügen der Listener da.

Screenshot Text-Input Example

Demo

circle-info

Es gibt vorgefertigte Listener-Funktionen, welche im Beispiel benutzt werden.

Implementation

Für den vollen Code: observableTextInputExample.jsarrow-up-right

Observable Color-Picker Beispiel

In diesem Beispiel-Projekt wird gezeigt wie ein Color-Picker mit dem Observable gebaut werden kann. Es gibt ein Observable das die Farbe verwaltet, an welches sich Listener wie Background, Labels und Inputs registrieren können. Die Input-Felder (Text-Input und Slider) sind dabei nicht nur Listener sondern auch gleichzeitig dafür da, dem Observable neue Werte zu übermitteln. Die Elemente Text-Input und Slider-Input sind bidirektional mit dem Observerable verbunden. Um das zu demonstrieren wurden Buttons im UI hinzugefügt zum an- und abmelden der Listener.

Screenshot Color-Picker Example

Demo

Implementation

circle-info

Der observierte Farbwert ist als Triple implementiert:triple(red, green, blue)

Für den vollen Code: observableColorPickerExample.jsarrow-up-right****

Observable HttpGet-Joke Beispiel

In diesem Beispiel-Projekt gibt es ein Observable das Witze verwaltet. Die Witze werden mit Klick auf den Button von einem REST-API abgefragt. Sobald ein neuer Witz veröffentlich wird, werden alle Listener informiert. Es existieren zwei Listener, der eine rendert die Witze auf dem UI und der andere löst ein Text-To-Speech-Skript aus.

Screenshot Joke-Example

Demo

Implementation

Für den vollen Code: observableHttpGetJokeExample.jsarrow-up-right****

HTTP-Programmierschnittstelle

Für dieses Beispiel wurde extra eine Funktionen erstellt um HTTP-Get anfragen zu tätigen. Sie bieten einen einfachen Weg, Daten von einer URL zu erhalten.

****HttpGet arrow-up-right(asynchron)

Mit der Funktion HttpGet wird asynchrone anfrage abgesetzt. Die Anfrage wird nach 30 Sekunden Time-out automatisch beendet, wenn vom Webserver bis dahin keine Antwort kommt. Die Funktion HttpGet erwartet als ersten Parameter eine URL und als zweiten Parameter eine Callback-Funktion __mit der Antwort vom Webserver.

Beispiel:

Analog zu HttpGet gibt es die Synchrone-Variante: HttpGetSync. Denn Callback braucht es nicht, da der Response direkt als Rückgabewert zurück gegeben werden kann.

Beispiel mit Box:

Verwendung

circle-info

Die Titel der Funktionen sind mit einem Link zur Implementation verknüpft.

Die Funktion Observable nimmt einen initialen Startwert und erstellt ein Observable.

Observable-Funktionen

observableBodyarrow-up-right (der Kern des Observable)

Das Observable-Konstrukt observableBody repräsentiert der Körper der Observable-Funktionen:

Der observableBody wird bei diesen Funktion immer zurückgegeben. Es ermöglicht eine Verkettung der Funktionen mit einem Observable.

triangle-exclamation
circle-info

Die Variable, die das Observable enthält, kann mit dem const Schlüsselwort deklariert werden und ist somit auch immutable. Dadurch kann diese Variable nicht überschrieben werden und es können dann keine Listener hinzugefügt werden oder entfernt werden.

Mit der Funktion addListener wird dem Observable ein neuer Listener hinzugefügt.

circle-info

Der aktuelle Wert des Observables wird beim Registrieren sofort dem neuen Listener mitgeteilt.

triangle-exclamation
circle-info

Mit bis zu 100 Listener und vielen Wertänderungen (zb. 100'000) auf einmal hat das Observable kein Problem.

Die Funktion removeListener entfernt den übergebenen Listener aus dem Observable.

Die Funktion removeListenerByKey entfernt ein Listener aus dem Observable anhand des übergeben Schlüssels.

Mit der Funktion setValue wird dem Observable ein neuer Wert gegeben. Das Observable informiert danach alle Listener.

Mit der Funktion getValue erhält man den aktuellen Wert vom Observable.

Mit der Funktion newListenerWithCustomKey wir ein neuer Listener erstellt. Die Funktion nimmt als erstes den Schlüssel, als zweites die Funktion, die auf die Wertänderung reagiert, entgegen.

triangle-exclamation
triangle-exclamation

Mit der Funktion newListener wir ein neuer Listener erstell. Der Key muss im Vergleich zu newListenerWithCustomKey nicht angeben werden, weil dieser automatisch generiert wird.

circle-info

Der generateRandomKey erzeugt einen String der Länge sechs mit zufälligen Buchstaben (Gross-/Kleinschreibung) & Zahlen. Siehe implementation: generateRandomKeyarrow-up-right

Mit der Funktion setListenerKey wird einem Listener ein neuer Schlüssel zugewiesen.

Mit der Funktion getListenerKey wird der Schlüssel von einem Listener abgefragt.

Helferfunktion

Mit der Funktion logListenersToConsole werden die Listener eines Observables auf der JavaScript Konsole ausgegeben.

Last updated

Was this helpful?