Si vous souhaitez améliorer la qualité globale de votre code, vous souhaiterez peut-être garder vos modèles de données parfaitement découplés des vues sous-jacentes.
Les frameworks fonctionnels-réactifs ou les bibliothèques d'interface utilisateur comme Rimmel.js, qui prennent entièrement en charge les observables, vous permettent de définir vos modèles en tant que flux observables (par exemple : flux de données simples entrants, flux de données sortants) en plus d'une conception peu connue. modèle qui est l'adaptateur d'événement.
Les adaptateurs d'événements vous aident à mapper tous les événements sources (par exemple : MouseEvent, PointerEvent, KeyboardEvent, etc. du DOM) au format réellement utilisé par vos modèles de données, afin qu'ils soient libérés de cette tâche de conversion et soient finalement découplés du Interface utilisateur.
Rimmel simplifie la connexion d'un tel flux au DOM :
import { rml } from 'rimmel'; const component = () => { const total = new Subject().pipe( map(x => doSomethingWith(x)), ); return rml`${stream}`; }
La liaison est triviale : Rimmel connecte les événements de clic provenant du bouton directement dans votre flux observable, qui recevra des instances de PointerEvent à chaque fois que vous cliquez sur le bouton.
Jusqu'ici, tout va bien. Que se passe-t-il si votre flux doit extraire des données de plusieurs sources et se comporter différemment en fonction de chacune ?
Créons un compteur simple avec un bouton d'incrémentation et un bouton de décrémentation, chacun en ajoutant ou en soustrayant un.
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}`; }
Cela fonctionne, mais la partie modèle inclut une certaine logique, qui est un anti-modèle. Idéalement, nous devrions nous efforcer d'avoir des modèles sans logique pour maximiser la testabilité globale.
Ainsi, avec Rimmel 1.2, vous disposez d'une nouvelle fonctionnalité, les Event Mappers, qui vous aident exactement dans ce domaine. Ils vous aident à mapper les événements DOM en fonction des besoins de votre modèle, afin que vous puissiez garder la logique parfaitement séparée du modèle. Voici comment cela fonctionne.
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 est l'ajout innovant ici : un outil de création de pipeline qui fonctionne à l'opposé de la fonction pipe() dans RxJS. Alors que cette dernière applique des transformations à la sortie d'un flux, reversePipe() les applique à l'entrée.
De cette façon, vous êtes sûr que votre flux principal Subject/BehaviorSubject/Observer/EventListener obtient toujours les données dans les formats souhaités et vous conservez votre adaptateur comme une préoccupation distincte.
Vous pouvez utiliser n'importe quel opérateur RxJS dans vos pipelines inverses. Souhaitez-vous filtrer uniquement certains événements, comme lorsque l'utilisateur appuie sur Entrée, plutôt que sur toute autre touche ? Utilisez simplement l'opérateur de filtre :
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}`; };
En ce qui concerne les tests unitaires, il s'agit d'un ajout minuscule mais utile qui rendra les tests plus simples et plus efficaces.
Découvrez les mappeurs d'événements en action sur ce Stackblitz
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3