欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Angular:Observable 有大用

   Observable 功能非常的强大,在 Angular 框架里大量的使用了 Observable 这种东西,比如表单,HTTP,路由等等。

   这个课程的目的是理解 Observable 里面的一些关键概念,比如怎么样创建一个 Observable,准备一个 Observer 处理在 Observable 上发生的事情,比如怎么使用它生产出来的数据,遇到了错误怎么处理,完成以后要做的事情。

   封面摄影:alfonso maseda varela

来自  https://ninghao.net/course/7729


# git branch         #查看一下当前的分支

# git log                #查看一下在当前分支上作的提交

# git checkout master         #切换到master分支

# git merge async-route            #合并 async-route 到当前分支

# git log                            #查看一下在当前分支上作的提交

# git checkout -b observable                #创建并切换分支

# git push origin async-route                #推送到远程 origin 的 async-route 分支

# git push origin master                #推送到远程 origin 的 master 分支

# git push origin observable            #推送到远程 origin 的 observable 分支

# git remote -v                                #查看远程分支


# ng generate component modules/demo/obeservable-demo            #生成一个组件  obeservable-demo   

CREATE src/app/modules/demo/obeservable-demo/obeservable-demo.component.html (31 bytes)

CREATE src/app/modules/demo/obeservable-demo/obeservable-demo.component.spec.ts (663 bytes)

CREATE src/app/modules/demo/obeservable-demo/obeservable-demo.component.ts (314 bytes)

CREATE src/app/modules/demo/obeservable-demo/obeservable-demo.component.css (0 bytes)

UPDATE src/app/modules/demo/demo.module.ts (882 bytes)








介绍与准备

1)介绍(Observable)

   Observable 功能非常的强大,在 Angular 框架里大量的使用了 Observable 这种东西,比如表单,HTTP,路由等等。

   这个课程的目的是理解 Observable 里面的一些关键概念,比如怎么样创建一个 Observable,准备一个 Observer 处理在 Observable 上发生的事情,比如怎么使用它生产出来的数据,遇到了错误怎么处理,完成以后要做的事情。

   再理解一下什么是订阅,怎么取消订阅 Observable 。操作员可以处理 Observable 上生产出来的数据,Rxjs 里提供了 100 多个可以做不同事情的操作员。使用 Pipe 可以组合使用这些操作员。

来自  https://ninghao.net/video/7731#toc


2)准备项目(Observable)


先检查一下现在当前的分支,

# git branch 

显示是在 async-route 分支,这是我们之前介绍异步路由的时候创建的一个分支,查看一下在这个分支上做的提交。

# git log

最后一次提交是 Custom preloading strategy 。

把当前分支切换到 master,

# git checkout master

在这个分支上做一次合并,要合并的是 async-route 这个分支,

# git merge async-route

合并之后再查看一下这个分支上的提交,

# git log

最后一次也会是 Custom preloading strategy 。

下面可以再去创建一个新的分支,并且切换到这个新的分支上,这个分支的名字可以是 observable。

# git checkout -b obervable

再去推送一下几个本地的分支,推送到 origin 这个远程,先推送一下 async-route 分支,

# git push origin async-route

然后再推送一下 master 分支。

# git push origin master

最后再推送一下 observable 。

# git push origin observable 

在这个课程里我对项目的修改都会保存在这个 observable 分支上,

# git remote -v 

到时候你可以找到这个项目的远程仓库,然后检查一下我在 observable 分支上做的提交。

我一直在 master 分支上进行操作

来自   https://ninghao.net/video/7732#info


3)准备 Observable 演示组件


在终端给项目生成一个组件,在这个组件里演示一下 Observable , ng generate 生成一个 component 放在 modules/demo 的下面,名字叫 observable-demo 。

# ng generate component modules/demo/obervable-demo   ( # ng g c modules/demo/obervable-demo  )

回到项目,先打开刚才创建的组件的视图文件,在里面添加一个标题,文字是 Observable,下面再添加一个段落文字,Demonstrate how observable works.

然后打开 Demo 模块的路由模块,在里面添加一条新的路由,路由的 path 设置成 observable,路由对应的 component,用一下刚才创建的 ObservableDemoComponent 。

再打开 DemoComponent 的视图文件,在 sidebar 里面,添加一个新的链接,链接上的文字是 Observable,地址是 ./observable。

预览

回到浏览器,打开 demo,然后点击打开 observable,界面上显示的就是 ObservableDemoComponent 组件的视图。

来自  https://ninghao.net/video/7733#info


Observable

4)Observable:数据生产线


在 Observable 里面可以使用各种不同的方式生成数据,比如 Observable 上的数据可能来自一些事件,HTTP 请求的响应等等。我们可以订阅 Observable 上产生的数据,订阅的时候可以提供一些方法,在这些方法里可以设置怎么样使用在 Observable 上产生的各种数据。

Observable 并不是 Angular 框架里特有的东西,只不过 Angular 框架里大量的使用了 Observable,相关的功能是 rxjs 提供的。

演示

下面我们演示一下 Observable 的一般用法。打开之前创建的 ObservableDemoComponent 组件,在组件里可以添加一个属性,名字叫 demoObservable ,以后你可能会看到一些名字后面带个 $ 后缀,这是一种惯用的命名 Observable 的方法。

这个属性的类型是 Observable,这个 Observable 上产生的数据的类型是 string。

在组件的 ngOninit 方法里可以创建一个 Observable。把要创建的 Observable 交给 this.demoObservable 属性。

创建 Observable 的方法有很多,我们先用 rxjs 里提供的 of 这个方法创建一个 Observable。 这个 of 来自 rxjs 。

使用这个方法创建 Observable 的时候可以提供一些值,这些值就是在这个 Observable 上生产出来的数据。随便添加几个字符串类型的值。

订阅

Observable 上的数据,只有在订阅它的时候才会生产出来。也就是如果没人订阅使用 Observable,这个 Observable 上面就不会生产出来任何的数据。

打开这个组件的模板文件,可以添加一个按钮,按钮文字是 Subscribe,在这个按钮上绑定一个点击事件,点了这个按钮,执行组件里的 onClick 方法。

回到这个组件,添加一个 onClick 方法,在这个方法里可以去订阅一下 demoObservable,this.demoObservable,用一下它上面的 subscribe 方法,提供一个方法参数,这个方法可以决定怎么样使用在 demoObservable 上面生产出来的数据,给这个数据起个名字,叫 value ,要做的事情可以简单的在控制台上输出 demoObservable 上面生产出来的数据。

预览

回到浏览器,按一下 Observable 演示组件上的这个 Subscribe 方法,这样就会订阅组件里的那个 demoObservable,订阅它的时候提供了一个方法,这个方法做的事情就是在控制台上输出订阅的 Observable 上面生产出来的数据。所以在控制台上你会看到 hello,hola 还有 您好 这几个值。

来自   https://ninghao.net/video/7735#info

5)Observer:处理生产线上发生的事情


订阅 Observable 的时候,可以给 subscribe 方法提供一个 Observer 对象,在这个对象里面,可以设置一下在 Observable 上发生的不同的事情,主要会发生三种事情。Observable 上产生数据,Observable 出现了错误,还有 Observable 完成了。

添加一个 observer ,它是一个对象,对象里有三个属性,一个是 next ,它的值是个方法,这个方法里面可以设置一下 Observable 上生产出来数据之后要做的事情。数据的名字可以叫它 value ,要做的事情是在控制台上输出生产出来的这个数据。

observer 上还可以添加一个 error 属性,这个属性的值也是一个方法,这个方法做的事情就是在 Observable 上发生错误的时候要做些什么。可以在控制台上输出 error。

最后还有一个 complete 属性,值是个方法,在这个方法里,你可以设置 Observable 完成以后要做的事情,输出一个 Demo observable completed.

再把创建的这个 observer,交给 subscribe 方法。这样在订阅的这个observable上面产生数据的时候会执行这个observer上面的next,如果发生错误就会执行observer上面的error,  observable 完成了会执行observer上面的complete (一般都会执行吧)

预览

回到浏览器,按一下 Subscribe 按钮,这次订阅组件里的 demoObservable 的时候,提供了一个 observer 对象,它里面设置了不同情况下要做的事情,比如在有数据的时候,要做的事情就是在控制台上输出这个数据。

这个 Observable 没有发生任何错误,所以没有输出错误。

Observable 完成以后,输出了一个 Demo observable completed.

在订阅 Observable 的时候提供的 Observer 对象里面,你不需要提供所有的属性,因为有些 Observable 永远不会完成,所以订阅它的时候在 observer 里面提供 complete 属性就没有意义了。

来自  https://ninghao.net/video/7736#info


6)Subscription:订阅


使用 Observable 上的 subscribe 方法可以订阅这个 Observable,订阅之后会返回一个 Subscription,就是订阅。这个订阅上面有个 unsubscribe 方法可以取消订阅 Observable。

在这个组件里面,可以添加一个新的属性,名字是 demoSubscription,它的类型是 Subscription ,来自 rxjs 。

然后在 ngOnInit 方法里面,创建这个 Observable 可以换一种方法,这里可以用一下 interval ,它也来自 rxjs,给它提供一个数字参数,比如 1000,这样创建的这个 Observable ,每隔一秒钟就会生产出一个数字数据。

这个 Observable 的数据类型可以先设置成 any 。

订阅

在 onClick 方法里,订阅了一下 demoObservable ,它会返回一个订阅,把它交给 this.demoSubscription。然后可以在这个组件里再添加一个方法,名字是 unsubscribe ,在这个方法里,用一下 this.demoSubscription 这个订阅上的 unsubscribe 方法。取消订阅 demoObservable 。

视图

打开这个组件的模板文件,在这里可以再添加一个按钮元素,按钮上的文字设置成 Unsubscribe ,点击这个按钮,执行一下组件里的 unsubscribe 这个方法,这个方法干的事情就是取消订阅 demoObservable 。

预览

打开浏览器可以预览一下,按一下 Subscribe 按钮,订阅 demoObservable,开始接收从这个 Observable 上生产出来的数据,得到了这个数据之后会把它输出到控制台上。

你会发现,每隔一秒钟的时候,就会输出一个数字。 这个 Observable 会一直产生数据,这些数据也会一直在控制台上输出。

按一下 Unsubscribe 按钮,可以取消订阅这个 Observable。这样它也就不会再产生数据了。

按一下 Subscribe,订阅,开始接收 Observable 上的数据,再按一下 Unsubscribe ,可以取消订阅。

来自  https://ninghao.net/video/7737#info


7)组件销毁后取消订阅


按一下 Subscribe 订阅 Observable 开始接收来自 Observable 上的数据。现在可以离开这个组件,打开应用的其它的地方,你会发现控制台仍然会输出接收到的数据。在销毁组件之后,我们可以取消 Observable 的订阅。

回到项目,打开 ObservableDemoComponent 组件,让这个组件实施一下 OnDestroy 接口。然后在类里面添加一个 ngOnDestroy 方法,组件在销毁的时候会执行这个方法。

在这个方法里,先在控制台上输出点文字,ngOnDestroy: Unsubscribe demo observable. 下面再执行一下 this.demoSubscription 上的 unsubscribe 方法,取消订阅。

预览

下面再回到浏览器试一下,按一下 Subscribe 订阅,开始接收数据。 然后打开应用的其它的地方,销毁 ObservableDemoComponent 组件的时候,执行了组件里的 ngOnDestroy 方法,在这个方法里取消了订阅 demoObservable。

来自  https://ninghao.net/video/7738#info


8)Operators:操作员


我们可以使用一些操作员方法加工处理 Observable 生产出来的数据。按一下 Subscribe 按钮订阅 Observable 之后,会在控制台上输出生产出来的一些数字。现在我想用一个操作员方法,处理一下生产出来的这个数字,比如可以在它前面加上一个 # 号。

回到项目,在 ObservableDemoComponent 组件的 ngOnInit 里面,用了一下 rxjs 里提供的 interval 创建了一个 Observable 。现在可以给这个 Observable 单独起个名字,比如叫它 someNumbers 。

然后在文件顶部导入一个操作员方法,来自 rxjs/operators,用一下它里面的 map 这个操作员方法。

在 ngOnInit 里面,用一下这个 map 提供一个方法参数,参数的值是 Observable 上生产出来的数据,比如叫它 value,要做的操作是在这个值的前面加上一个 # 号,这里我们用了一个字符模板。

这个操作员方法会返回一个函数,可以给它起个名字,比如 transformValue 。

下面用这个返回过来的函数处理一下 someNumbers 这个 Observable。这个函数返回的值是一个 Observable ,交给组件里的 demoObservable 这个属性。

预览

回到浏览器再试一下,按一下 Subscribe 按钮,订阅了 demoObservable,这次订阅之后输出的 Observable 上的数据里面都会带着一个 # 号。

这是因为,这次我们用了一个 map 操作员,让它做的事情就是在 Observable 上生产出来的数据的前面,加上一个 # 号。

来自  https://ninghao.net/video/7739#info


9) Pipe:操作员组合

我们可以把一些操作员方法组合到一块儿用,可以使用 pipe 函数去把它们组合到一起用,这里可以使用一下这个 pipe 函数,它来自 rxjs 。

在这个 pipe 里面,可以添加一些操作员方法,把之前的 map 操作员先放进来,逗号分隔一下,可以继续添加其它的操作员方法。

比如用一下 filter,它可以根据条件过滤出一些值,这个 filter 来自 rxjs/operators 。

给 filter 提供一个方法,有个 value 参数,类型是 number ,过滤出这个 value 除以 2 的余数不等于 0 的值。也就是过滤出所有的奇数值。

pipe 函数返回的这个函数是 transformValue,用这个 transformValue ,把上面的 someNumbers 这个 Observable 交给这个函数。

这样这个 someNubmers 生产出来的值,会通过 pipe 里的这些操作员来处理, filter 会过滤出奇数的值,然后 map 会在这些值前面加上一个 # 号。

预览

回到浏览器再试一下,按一下 Subscribe,你会发现,这次在控制台上输出的 Observable 里的值都是奇数的,并且这些值的前面都有一个 # 号。

来自  https://ninghao.net/video/7740#toc


10)使用 Observable 上的 Pipe 方法


pipe 函数可以组合一些操作员方法,然后用 pipe 返回的函数去加工一个 Observable。另外我们还可以直接使用 Observable 上的 pipe 方法。这样写起来更简单一些。

比如这里,我们可以先创建一个 Observable 可以使用这个 interval 来创建一个,然后可以直接给它接上一个 pipe ,可以把上面的这个 pipe 移过来。

预览

下面再到浏览器上试一下,按一下 Subscribe,开始接收数据,在控制台上输出的这些数字,这些数字都会是用 filter 操作员筛选出来的奇数,map 操作员会在这些值的前面加上一个 # 号。

来自  https://ninghao.net/video/7741#info




11)Bug:Cannot read property 'unsubscribe' of undefined


现在应用有个小 Bug,打开 Demo,再点击打开 Observable,然后试着离开这里。控制台上会出现提示,Cannot read property unsubscribe of undefined。

这是因为现在销毁这个组件会执行它的 ngOnDestroy ,在这个方法里执行了一下 demoSubscription 上的 unsubscribe 取消订阅。

不过如果没有按组件上的这个 Subscribe 按钮,就不会有订阅,所以也就不能取消订阅。

回到组件,找到 ngOnDestroy 方法,这里在取消订阅的时候可以做一下判断,if this.demoSubscription ,如果有订阅再执行它上面的 unsubscribe 方法。

预览

再回到浏览器试一下,这次就可以正常离开 observable 页面,访问其它的地方了。

来自  https://ninghao.net/video/7742#toc

普通分类: