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()
)
}
}

[RxJS] RxJS Advanced Patterns Operate Heavily Dynamic UIs的更多相关文章

  1. 使用angular的HttpClient搭配rxjs

    一.原Http使用总结 使用方法 在根模块或核心模块引入HttpModule 即在AppModule或CoreModule中引入HttpModule: import { HttpModule } fr ...

  2. RxJS速成 (上)

    What is RxJS? RxJS是ReactiveX编程理念的JavaScript版本.ReactiveX是一种针对异步数据流的编程.简单来说,它将一切数据,包括HTTP请求,DOM事件或者普通数 ...

  3. RxJS v6 学习指南

    为什么要使用 RxJS RxJS 是一套处理异步编程的 API,那么我将从异步讲起. 前端编程中的异步有:事件(event).AJAX.动画(animation).定时器(timer). 异步常见的问 ...

  4. 构建流式应用—RxJS详解[转]

    目录 常规方式实现搜索功能 RxJS · 流 Stream RxJS 实现原理简析 观察者模式 迭代器模式 RxJS 的观察者 + 迭代器模式 RxJS 基础实现 Observable Observe ...

  5. 【CuteJavaScript】Angular6入门项目(3.编写服务和引入RxJS)

    本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...

  6. rxjs 入门--环境配置

    原文: https://codingthesmartway.com/getting-started-with-rxjs-part-1-setting-up-the-development-enviro ...

  7. RxJS 6有哪些新变化?

    我们的前端工程由Angular4升级到Angular6,rxjs也要升级到rxjs6.  rxjs6的语法做了很大的改动,幸亏引入了rxjs-compact包,否则升级工作会无法按时完成. 按照官方的 ...

  8. [译]Rxjs&Angular-退订可观察对象的n中方式

    原文/出处: RxJS & Angular - Unsubscribe Like a Pro 在angular项目中我们不可避免的要使用RxJS可观察对象(Observables)来进行订阅( ...

  9. Dynamic Signals and Slots

    Ref https://doc.qt.io/archives/qq/qq16-dynamicqobject.html Trolltech | Documentation | Qt Quarterly ...

随机推荐

  1. bootstrap-table的一些配置参数例子

    $('#reportTable').bootstrapTable({ method: 'post', url: '/qStock/AjaxPage', dataType: "json&quo ...

  2. Design Excel Sum Formula

    Your task is to design the basic function of Excel and implement the function of sum formula. Specif ...

  3. 「java.util.concurrent并发包」之 CopyOnWrite

    一 CopyOnWrite容器概述 Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容C ...

  4. Android Monkey压测命令

    测试步骤:1.安装ADB2.连接被测手机和电脑3.打开CMD命令行4.输入monkey命令adb shell monkey -p your.package.name --pct-touch 30 -- ...

  5. vue开发环境配置跨域,一步到位

    本文要实现的是:使用vue-cli搭建的项目在开发时配置跨域,上线后不做任何任何修改,接口也可以访问,前端跨域解决方案 production:产品 生产环境 development:开发 开发环境 1 ...

  6. WPF 位图处理相关类

    位图的存储方式 开始之前,先了解下位图的存储方式 位图的像素都分配有特定的位置和颜色值.每个像素的颜色信息由RGB组合或者灰度值表示,根据位深度,可将位图分为1.4.8.16.24及32位图像等.每个 ...

  7. Codeforces 1247C. p-binary

    传送门 首先 $n=\sum_{i=1}^{ans}(2^{x_{ans}}+p)$ 可以变成 $n-ans \cdot p=\sum_{i=1}^{ans}2^{x_{ans}}$ 注意到如果 $n ...

  8. docker使用的一些需要注意事项

    1.程序需要前台运行 程序必须前台执行,如果是java进程的话  不要有nohup   或者使用service的方式进行后台运行 否则可能会出现频繁启动应用的问题 原因就是docker只能管理运行中的 ...

  9. C#数字前补0

    [TestMethod] public void Test8() { ; string b = string.Format("{0:000000}", a); , '); }

  10. promise, async和await

    最开始实现异步的方法:回调函数 method1(function(err, result) { if (err) { throw err; } method2(function(err, result ...