チェック遊び場。
インポート {カウンタ、CountDownState、ConterStateKeys、PartialCountDownState} ./counter 'から インポート {件名、観測、マージ、タイマー、NEVER、combineLatest} rxjs'から。 インポート 'rxjs /事業者から{マップ、mapTo、switchMap、むしれ、スキャン、startWith、shareReplay、distinctUntilChanged、withLatestFrom、タップ} 。 // EXERCISE説明============================== / ** *プロパティ名に`ConterStateKeys`を使用してください。 *どこかに`counterUI.`を入力してcounterUIのAPIをExplort。;) * *カウンターのすべての機能を実装します * 1。スタート、カウンタを一時停止します。そして、0(+)でカウンターを再起動します * 2.一時停止数(++)から再びそれを起動します (+++)をカウントしながら、*ボタンに設定してください。3.もしを入力値に設定されたカウンタ値をクリックすると リセットボタンがクリックされた場合は、初期状態に* 4リセットを(+) * 5。もしあれば、ボタンはカウントアップをクリックするとカウントアップカウントダウンボタンはダウンカウントをクリックする(+) * 6.変更間隔入力tickSpeed入力の変化は、(++)場合 場合* 7.変更はカウントアップ入力countDiffの変更(++) * 8.実行し、他の性能最適化をレンダリングするの世話をしますだけでなく、リファクタリング(+) * / // ======================================= =========================== // = BASEの観測================== ================================== // == SOURCEの観測========== ======================================== CONST initialConterState:CountDownState = { isTicking:偽、 :カウント 0 、 カウントアップ:真、 tickSpeed: 200 、 countDiffを: 1 }。 CONST counterUI = 新しいカウンタ( document.body、 { initialSetTo:initialConterState.count + 10 、 initialTickSpeed:initialConterState.tickSpeed、 initialCountDiff:initialConterState.countDiff、 } )。 // === STATEの観測=========================================== ======= constの programmaticCommandSubject = 新しい件名<PartialCountDownState> (); CONSTは counterCommands $ = (マージ :counterUI.btnStart $ .pipe(mapTo({isTicking 真))} :counterUI.btnPause $の.pipe(mapTo({isTicking 偽))} N counterUI.btnSetToの$ .pipe(マップ( => ({数:Nを})))、 counterUI.btnUp $ .pipe(mapTo({カウントアップ:真}))、 counterUI.btnDown $ .pipe(mapTo({カウントアップ:偽}))、 counterUI.btnReset $ .pipe(mapTo({...} initialConterState))、 counterUI.inputTickSpeed $ .pipe(マップ(N => ({tickSpeed:N})))、 counterUI.inputCountDiff $ .pipe(マップ(N => ({countDiff:N})))、 programmaticCommandSubject.asObservable() )。 CONST counterState $ = counterCommands $ .pipe( startWith(initialConterState)、 スキャン((状態、コマンド) => ({ ...状態、 ...コマンド }))、 shareReplay( 1 ) )。 // ===相互作用観測=========================================== = constの数$ = counterState $ .pipe( queryState( '数' ) ); constの isTicking $ =counterState $ .pipe( queryState( 'isTicking' ) ); constの intervalTick $ = isTicking $ .pipe( switchMap(isTicking?=> isTickingタイマー(0 、initialConterState.tickSpeed):NEVER) ); // =副作用============================================= ============ // == UI入力================================ =========================== のconst renderCountChange $ = カウントの$ .pipe( タップ((nは番号) => counterUI.renderCounterValue(N )) ); // == UI出力============================================ ============== のconstcommandFromTick $ = intervalTick $ .pipe( withLatestFrom(カウント$、(_、カウント) => )カウント タップ((カウント:数) => programmaticCommandSubject.next({カウント:++ カウント})) )。 // == SUBSCRIPTION ============================================= =========== マージ( // 入力副作用 renderCountChangeの$、 // 出力副作用 commandFromTick $ ) .subscribe(); // ==作成方法============================================ ======== 関数queryState(名){ リターン機能(O $){ リターンOの$の.pipe( 摘む(名)、 distinctUntilChanged() ) } }