Check the playground.

import {Counter, CountDownState, ConterStateKeys, PartialCountDownState} from './counter'
import { Subject, Observable, merge, timer, NEVER, combineLatest} from 'rxjs';
import { map, mapTo, switchMap, pluck, scan, startWith,shareReplay, distinctUntilChanged, withLatestFrom, tap} from 'rxjs/operators'; // EXERCISE DESCRIPTION ============================== /**
* Use `ConterStateKeys` for property names.
* Explort the counterUI API by typing `counterUI.` somewhere. ;)
*
* Implement all features of the counter:
* 1. Start, pause the counter. Then restart the counter with 0 (+)
* 2. Start it again from paused number (++)
* 3. If Set to button is clicked set counter value to input value while counting (+++)
* 4. Reset to initial state if reset button is clicked (+)
* 5. If count up button is clicked count up, if count down button is clicked count down (+)
* 6. Change interval if input tickSpeed input changes (++)
* 7. Change count up if input countDiff changes (++)
* 8. Take care of rendering execution and other performance optimisations as well as refactoring (+)
*/ // ================================================================== // = BASE OBSERVABLES ====================================================
// == SOURCE OBSERVABLES ==================================================
const initialConterState: CountDownState = {
isTicking: false,
count: 0,
countUp: true,
tickSpeed: 200,
countDiff:1
}; const counterUI = new Counter(
document.body,
{
initialSetTo: initialConterState.count + 10,
initialTickSpeed: initialConterState.tickSpeed,
initialCountDiff: initialConterState.countDiff,
}
); // === STATE OBSERVABLES ==================================================
const programmaticCommandSubject = new Subject<PartialCountDownState>();
const counterCommands$ = merge(
counterUI.btnStart$.pipe(mapTo({isTicking: true})),
counterUI.btnPause$.pipe(mapTo({isTicking: false})),
counterUI.btnSetTo$.pipe(map(n => ({count: n}))),
counterUI.btnUp$.pipe(mapTo({countUp: true})),
counterUI.btnDown$.pipe(mapTo({countUp: false})),
counterUI.btnReset$.pipe(mapTo({...initialConterState})),
counterUI.inputTickSpeed$.pipe(map ( n => ({tickSpeed: n}))),
counterUI.inputCountDiff$.pipe(map ( n => ({countDiff: n}))),
programmaticCommandSubject.asObservable()
); const counterState$ = counterCommands$
.pipe(
startWith(initialConterState),
scan((state, command) => ({
...state,
...command
})),
shareReplay(1)
); // === INTERACTION OBSERVABLES ============================================
const count$ = counterState$.pipe(
queryState('count')
); const isTicking$ = counterState$.pipe(
queryState('isTicking')
);
const intervalTick$ = isTicking$.pipe(
switchMap(isTicking => isTicking ? timer(0, initialConterState.tickSpeed): NEVER)
);
// = SIDE EFFECTS =========================================================
// == UI INPUTS ===========================================================
const renderCountChange$ = count$
.pipe(
tap((n: number) => counterUI.renderCounterValue(n))
); // == UI OUTPUTS ==========================================================
const commandFromTick$ = intervalTick$
.pipe(
withLatestFrom(count$, (_, count) => count),
tap((count: number) => programmaticCommandSubject.next({count: ++count}))
); // == SUBSCRIPTION ======================================================== merge(
// Input side effect
renderCountChange$,
// Outputs side effect
commandFromTick$
)
.subscribe(); // == CREATION METHODS ====================================================
function queryState (name) {
return function (o$) {
return o$.pipe(
pluck(name),
distinctUntilChanged()
)
}
}

最新文章

  1. net面试题
  2. cocos布局分析
  3. js传递参数中包含+号时的处理方法
  4. HDU 4777 Rabbit Kingdom
  5. 修改cookie
  6. mustache.js使用基本(三)
  7. linux top结果保存到文本上
  8. DOM 核心
  9. 用javaScript获取页面元素值
  10. c# 转换成时间类型
  11. java学习笔记39(sql事物)
  12. save
  13. CSS3多媒体查询
  14. 将ArcGIS Server的JSON转化为SHP文件
  15. “Hello World!”团队第六周第七次会议
  16. layui-table渲染不出来
  17. 关于jsonp的学习
  18. 20181030noip模拟赛T1
  19. SublimeText插件cssrem : px转换为rem
  20. Convolutional Patch Networks with Spatial Prior for Road Detection and Urban Scene Understanding

热门文章

  1. 为什么fastjson字段为null时不输出空字符串?
  2. python字典改变value值方法总结
  3. 【Python基础】11_Python中的字符串
  4. axios 跨域携带cookie设置
  5. Web API 自动生成接口文档
  6. git 报错fatal: not a git repository (or any of the parent directories): .git
  7. Oracle使用基础
  8. js 数值精确运算使用math.js
  9. sql 存储过程笔记3
  10. Jmeter服务器压力测试使用说明