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`${stream}`; }
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, ist es gut. Was passiert, 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`${total}`; }
Das funktioniert, aber der Vorlagenteil enthält eine gewisse Logik, die ein Anti-Muster 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`${total}`; };
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${state}`; };
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
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3