发表于: 2017-05-28 23:33:15
1 1071
一、今天完成的事情
1.解决图片预览问题。
2.研究了一下富文本编辑器的用法。
3学习RxJS。
二、明天计划的事情
三、遇到的问题
1. 上传图片的,没上传成功,
原因是接口的不对,接口正确就好了。如图:
2. 如何理解 RxJS?
要做到通俗易懂,就得弄清楚 RxJS 的一些基础和概念。RxJS 整个库的基础就是 Observable,注意是 Observable ,不是 Observer,和观察者模式区别开。Observable 对象初探关于对 Observable 对象的理解,通过下面的代码就能有个大致的印象,看得出来 $clickStream 其内部可以连续产生新事件(或者值),并且在外部可以被监听。let button = document.getElementById('btn1');
let clickStream$ = Observable.create(function(observer){
button.addEventListener('click', function(event){
observer.next(event)
}, false);
});
clickStream$.subscribe(ev => console.log(ev));
其中 create 方法接受的那个函数,一般被俺称做 Producer(生产者)函数,subscribe 方法接受的那个函数,被俺称作回调函数(噗),然而事实上并不那么简单。Observable 里的 lazy 、cold 和 hotRx 中的 Observable 对象默认是 lazy 且 cold 的,lazy 说的是如果 Observable 对象的 subscribe 方法没有被调用,那么 Producer 函数也就不会被调用。cold 是说每调用一次 subscribe 方法,就会执行一次 Producer 来产生一个新的 Subscription 流,也就是不同的 Subscription 流内的状态不会相互影响。举个例子(JS Bin):let interval = Rx.Observable.create(observer => {
setInterval(() => observer.next(), 1000)
}).scan(x => x+1, 0); //累加器,从 0 开始,类似在内部定义了一个count,然后每次count++
// 1, 2, 3...
interval.subscribe(count => console.log('count1:'+count));
setTimeout(() => {
// 3s 后监听,同样得到 1, 2, 3... 而不是 4, 5, 6..
interval.subscribe(count => console.log('count2:'+count));
}, 3000);
如果要对象变成 hot 的,也就是不管调用 subscribe 多少次都是监听同一个流,那么就调用一下 Observable 对象的 share 方法,把它标记为 hot。上面的例子,如果我们希望在 3s 后监听是得到4, 5, 6...,那么在调用完 scan 的地方再调用一下 share 就可以了,这时候可以理解成和第一个subscribe监听的是同一个“流”。为啥 Rx 是这么设计的呢?我觉得也很奇怪。Cycle.js 的作者就对此也感到不解,所以重新设计了一个响应“流”库:staltz/xstream,只产生 hot 的“流”,我觉得更合理些,只是不知 Observable W3C 规范将来会怎么定义。Observable TransformObservable 对象上除了 subscribe ,还有一堆方法,用来把当前的“流”转成(transformTo)另一个“流”。比如 map 和 filter :
--1---3--5-----7------
map(i => i * 10)
--10--30-50----70-----
--1---2--3-----4-----5---6--7-8--
filter(i => i % 2 === 0)
------2--------4---------6----8--
在上面的两个例子中,函数返回的是新值,有时候还需要支持返回一个流,然后这个流的状态产生一个新流,比如下面的例子:
---1---2-----3--4----5----6---
endWhen( --------a--b--| )
---1---2-----3--4--|
Observable 类静态方法再说下 Observable 类上的静态方法,通常是工厂方法,用来定义流的产生(比如上面的 create);用来将其他对象转成流,比如 fromPromise,就是将一个 Promise 对象转成一个“有终点”的流:fromPromise( ----42 )
-----------------42|
还有用来将两个流合并,产生一个新的流的方法,比如 merge:
--1----2-----3--------4---
----a-----b----c---d------
merge
--1-a--2--b--3-c---d--4---
举个实际应用场景:电商 Detail 页面价格模型不知不觉说了这么多,掌握了上面的基本姿势,我们再来点实践,比如设计一个电商页面的价格数据模型层:在商品详情页面上,不同的 sku (最小库存单元,例如iPhone 7 32GB和 iPhone 7 128GB是两个不同的sku)价格不同,用户选择完具体的一个 sku 之后,要显示对应的价格,其实可以用流抽象出一个模型层:首先是选择 sku 的时候我们产生一个 dom 事件的流:
---ev----ev----ev----ev----
然后把这个事件流转变成 skuId$ (数据)流:---skuId----skuId----skuId---skuId----
然后把 skuId$ 流转成 skuId 对应的价格(数据)流:---price---price---price--price----
最后我们在 View 层面上 subcribe 一下 price$ 流,在回调函数里修改一下价格标签的innerHTML:price$.subscribe(price => $el.html(price));
当然,实际场景往往比这复杂多了,电商detail页面在电商前台页面中算比较复杂的了。
四、收获
1.学习富文本编辑器的用法。
2.学习RxJS。
评论