コードの全体的な品質を向上させたい場合は、データ モデルを基礎となるビューからきちんと分離しておくとよいでしょう。
Observable を完全にサポートする、Rimmel.js のような Functional-Reactive フレームワークや UI ライブラリを使用すると、あまり知られていない設計に加えて、モデルを Observable ストリーム (例: 単純なデータ入力、データ出力ストリーム) として定義できます。イベントアダプターであるパターン。
イベント アダプターは、ソース イベント (例: DOM の MouseEvent、PointerEvent、KeyboardEvent など) をデータ モデルで実際に使用される形式にマッピングするのに役立ちます。そのため、イベント アダプターはこの変換タスクから解放され、最終的にはUI。
Rimmel を使用すると、このようなストリームを DOM に簡単に接続できます。
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> `; }
バインディングは簡単です。リンメルはボタンからのクリック イベントを監視可能なストリームに直接接続し、ボタンがクリックされるたびに PointerEvent のインスタンスを受け取ります。
ここまでは順調です。ストリームが複数のソースからデータを取得する必要があり、それぞれに応じて異なる動作をする場合はどうすればよいでしょうか?
増分ボタンと減分ボタンを備えた単純なカウンターを作成してみましょう。それぞれのボタンから 1 を加算または減算します。
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> `; }
これは機能しますが、テンプレート部分にはアンチパターンであるロジックが含まれています。理想的には、全体的なテスト容易性を最大化するために、ロジックのないテンプレートを使用するように努めるべきです。
Rimmel 1.2 には、まさにそれを支援する新機能 Event Mappers があります。これらは、DOM イベントをモデルが必要とするものにマッピングするのに役立つため、ロジックをテンプレートから完全に分離することができます。その仕組みは次のとおりです。
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 はここでの革新的な追加機能であり、RxJS の Pipe() 関数とは逆に機能するパイプライン作成ツールです。後者はストリームの出力に変換を適用しますが、reversePipe() は入力に変換を適用します。
こうすることで、メインストリームの Subject/BehaviorSubject/Observer/EventListener が常に必要な形式でデータを取得できるようになり、アダプターを別個の関心事として保持することができます。
リバース パイプラインでは任意の RxJS オペレーターを使用できます。他のキーではなく、ユーザーが Enter キーを押したときなど、特定のイベントのみをフィルターで除外したいですか?フィルター演算子を使用するだけです:
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> `; };
単体テストに関しては、これは小さいですが便利な追加機能であり、テストをよりシンプルかつ効率的にすることができます。
この Stackblitz で動作しているイベント マッパーをチェックしてください
以上がrimmel.js でのイベント マッパーの使用: 簡単な概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。