Wenn Sie die Gesamtqualität Ihres Codes verbessern möchten, möchten Sie möglicherweise Ihre Datenmodelle sauber von den zugrunde liegenden Ansichten entkoppeln.
Funktional-reaktive Frameworks oder UI-Bibliotheken wie Rimmel.js, die Observables vollständig unterstützen, ermöglichen es Ihnen, Ihre Modelle zusätzlich zu einem wenig bekannten Design auch als Observable-Streams (z. B. einfache Daten-In- und Daten-Out-Streams) zu definieren Muster, das der Ereignisadapter ist.
Ereignisadapter helfen Ihnen dabei, alle Quellereignisse (z. B. das MouseEvent, PointerEvent, KeyboardEvent usw. des DOM) dem Format zuzuordnen, das tatsächlich von Ihren Datenmodellen verwendet wird, sodass sie von dieser Konvertierungsaufgabe befreit und letztendlich von der entkoppelt werden Benutzeroberfläche.
Rimmel macht es einfach, einen solchen Stream mit dem DOM zu verbinden:
import { rml } from 'rimmel'; const component = () => { const total = new Subject().pipe( map(x => doSomethingWith(x)), ); return rml` <button onclick="${stream}">click me</button> <div id="display">${stream}</div> `; }
Die Bindung ist trivial: Rimmel verbindet Klickereignisse, die von der Schaltfläche kommen, direkt mit Ihrem beobachtbaren Stream, der jedes Mal, wenn auf die Schaltfläche geklickt wird, Instanzen von PointerEvent empfängt.
So weit so gut. Was ist, wenn Ihr Stream Daten aus mehreren Quellen beziehen muss und sich je nach Quelle unterschiedlich verhält?
Lassen Sie uns einen einfachen Zähler mit einer Schaltfläche zum Erhöhen und Verringern erstellen, die jeweils eins addieren oder davon subtrahieren.
import { scan } from 'rxjs'; import { rml } from 'rimmel'; const component = () => { const total = new BehaviorSubject(0).pipe( scan((old, new) => old+new, 0), ); return rml` <button onclick="${() => total.next(1)}">inc</button> <button onclick="${() => total.next(-1)}">dec</button> <div>${total}</div> `; }
Das funktioniert, aber der Vorlagenteil enthält etwas Logik, was ein Anti-Pattern ist. Idealerweise sollten wir uns um logiklose Vorlagen bemühen, um die Testbarkeit insgesamt zu maximieren.
Mit Rimmel 1.2 gibt es also eine neue Funktion, Event Mappers, die genau dabei hilft. Sie helfen Ihnen dabei, DOM-Ereignisse den Anforderungen Ihres Modells zuzuordnen, sodass Sie die Logik perfekt von der Vorlage trennen können. So funktioniert es.
import { map, scan } from 'rxjs'; import { rml, reversePipe } from 'rimmel'; const Inc = reversePipe(map(() => 1)); const Dec = reversePipe(map(() => -1)); const component = () => { const total = new BehaviorSubject(0).pipe( scan((old, new) => old+new, 0), ); return rml` <button onclick="${Inc(total)}">inc</button> <button onclick="${Dec(total)}">dec</button> <div>${total}</div> `; };
reversePipe ist hier die innovative Ergänzung: ein Pipeline-Erstellungstool, das im Gegensatz zur Funktion „pipe()“ in RxJS funktioniert. Während Letzteres Transformationen auf die Ausgabe eines Streams anwendet, wendet reversePipe() sie auf die Eingabe an.
Auf diese Weise stellen Sie sicher, dass Ihr Hauptstream-Subject/BehaviorSubject/Observer/EventListener immer Daten in den von Ihnen gewünschten Formaten erhält, und Sie behalten Ihren Adapter als separates Anliegen.
Sie können jeden RxJS-Operator in Ihren Reverse-Pipelines verwenden. Möchten Sie nur bestimmte Ereignisse herausfiltern, z. B. wenn der Benutzer die Eingabetaste drückt, und nicht eine andere Taste? Verwenden Sie einfach den Filteroperator:
import { Subject, filter, map } from 'rxjs'; import { rml, inputPipe } from 'rimmel'; const UpperOnEnter = inputPipe( filter((e: Event) => e.key == 'Enter'), map((e: Event) => e.target.value.toUpperCase()), ); const Component = () => { const state = new Subject(); return rml` Type some text and hit Enter<br> <input onkeydown="${UpperOnEnter(state)}"> <div>${state}</div> `; };
Im Hinblick auf Unit-Tests ist dies eine kleine, aber nützliche Ergänzung, die Tests einfacher und effizienter macht.
Sehen Sie sich bei diesem Stackblitz Event-Mapper in Aktion an
Das obige ist der detaillierte Inhalt vonVerwenden von Event Mappern mit Rimmel.js: eine einfache Einführung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!