【CuteJavaScript】Angular6入门项目(3.编写服务和引入RxJS)
本文目录
- 一、项目起步
- 二、编写路由组件
- 三、编写页面组件
- 四、编写服务
- 1.为什么需要服务
- 2.编写服务
- 五、引入RxJS
- 1.关于RxJS
- 2.引入RxJS
- 3.改造数据获取方式
- 六、改造组件
- 1.添加历史记录组件
- 2.添加和删除历史记录
- 七、HTTP改造
- 1.引入HTTP
- 2.通过HTTP请求数据
- 3.通过HTTP修改数据
- 4.通过HTTP增加数据
- 5.通过HTTP删除数据
- 6.通过HTTP查找数据
四、编写服务
截止到这部分,我们的BooksComponent
组件获取和显示的都是本地模拟的数据。
接下来我们要开始对这些进行重构,让聚焦于为它的视图提供支持,这也让它更容易使用模拟服务进行单元测试。
1.为什么需要服务
我们不应该让组件来直接获取或保存数据,它们应该聚焦于展示数据,而数据访问的工作交给其他服务来做。
这里我们需要创建一个名为BooksService
的服务,让我们应用中所有的类都使用它来获取书本列表的数据,使用的时候,只需要将它通过Angular的依赖注入机制注入到需要用的组件的构造函数中。
知识点:
服务可以实现多个不同组件之间信息共享,后面我们还会将它注入到两个地方:
BooksService
中,使用该服务发送消息。
IndexService
中,使用该服务来展示消息。
接下来我们使用命令行,创建BooksService
:
ng g service books
在生成的books.service.ts
文件中:
// books.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
新导入了@Injectable
装饰器,是为了让BooksService
提供一个可注入的服务,并且它还可以拥有自己的待注入的依赖,简单理解就是如果你的服务需要依赖,那么你就需要导入它。
并且它接收该服务的元数据对象。
2.编写服务
接下来我们开始编写books.service.ts
服务。
- 导入服务所需组件
这里我们导入Books
和BookList
,并添加一个getBooks
方法来返回所有书本的数据,并且还需要添加一个getBooks
方法来返回指定id的书本信息:
// index.component.ts
import { Books } from './books';
import { BookList } from './mock-books';
@Injectable({
providedIn: 'root'
})
export class BooksService {
constructor() { }
getBookList(): Books[] {
return BookList;
}
getBook(id: number): Books{
return BookList.find(book => book.id === id)
}
}
在我们使用这个服务之前,需要先注册该服务,因为我们在使用ng g service books
命令创建服务时,CLI已经默认为我们添加了注册了,这是方法就是上面代码中的:
providedIn: 'root'
表示将我们的服务注册在根注入器上,这样我们就可以把这个服务注入到任何享用的类上了。
- 修改
IndexComponent
先删除BookList
的引入,并修改books
属性的定义:
// index.component.ts
import { BooksService } from '../books.service';
export class IndexComponent implements OnInit {
books : Books[];
ngOnInit() {}
}
然后注入我们的BooksService
服务,需要先往构造函数中添加一个私有的booksservice
,使用注入的BooksService
作为类型,理解成一个注入点:
// index.component.ts
constructor(private booksservice: BooksService) { }
之后我们需要添加一个getBooks
方法来获取这些书本数据,并在生命周期函数ngOnInit
中调用:
export class IndexComponent implements OnInit {
ngOnInit() {
this.getBooks();
}
getBooks(): void{
this.books = this.booksservice.getBookList();
}
}
- 修改
DetailComponent
我们先改造书本详情页的HTML结构:
<!-- detail.component.html -->
<div *ngIf="books" class="detail">
<h3>《{{books.title}}》介绍</h3>
<div>
<img src="{{books.url}}">
</div>
<p>书本标题: {{books.title}}</p>
<p>书本作者: {{books.author}}</p>
<p>书本id: {{books.id}}</p>
</div>
<div *ngIf="!books" class="detail">
<h3>暂无信息</h3>
</div>
知识点:
这里使用了*ngIf
指令,当条件为true
则显示其HTML内容。
// detail.component.ts
import { Books } from '../books';
import { BooksService } from '../books.service';
export class DetailComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private location: Location,
private booksservice: BooksService // 引入BooksService服务
) { }
books: Books; // 定义books类型
ngOnInit() {
this.getDetail()
}
getDetail(): void{
const id = +this.route.snapshot.paramMap.get('id');
this.getBooks(id);
}
getBooks(id: number): void {
this.books = this.booksservice.getBook(id);
}
}
这段代码,主要定义了getBooks
方法,当刚进入页面时,将书本id
传入getBooks
方法,去BooksService
去获取对应id的书本信息,并复制给变量books
,然后展示到页面。
改造之后,我们的页面显示依旧正常。
但是我们要知道,这背后的逻辑已经改变了。
五、引入RxJS改造项目
1.关于RxJS
这里简单介绍关键概念,具体可以查看 RxJS 官网,也可以参考 浅析Angular之RxJS。
什么是RxJS
RxJS全称Reactive Extensions for JavaScript
,中文意思: JavaScript的响应式扩展。
RxJS主要是提供一种更加强大和优雅的方式,来利用响应式编程的模式,实现JavaScript的异步编程。
RxJS优点
- 纯净性;
- 流动性;
RxJS核心概念
RxJS 是基于观察者模式和迭代器模式以函数式编程思维来实现的。RxJS 中含有两个基本概念:Observables
与 Observer
。
Observables
作为被观察者,是一个值或事件的流集合;而 Observer
则作为观察者,根据 Observables
进行处理。它们之间的订阅发布关系(观察者模式) 如下:
订阅:Observer
通过 Observable
提供的 subscribe()
方法订阅 Observable
。
发布:Observable
通过回调 next
方法向 Observer
发布事件。
———— 来源Angular修仙之路 RxJS Observable
另外这里列出来一些核心,具体还是看官网咯,并且下面使用到的时候会具体介绍。
Observable
(可观察对象): 表示一个概念,这个概念是一个可调用的未来值或事件的集合。Observer
(观察者): 一个回调函数的集合,它知道如何去监听由Observable
提供的值。Subscription
(订阅): 表示Observable
的执行,主要用于取消Observable
的执行。Operators
(操作符): 采用函数式编程风格的纯函数 (pure function
),使用像map
、filter
、concat
、flatMap
等这样的操作符来处理集合。Subject
(主体): 相当于EventEmitter
,并且是将值或事件多路推送给多个Observer
的唯一方式。Schedulers
(调度器): 用来控制并发并且是中央集权的调度员,允许我们在发生计算时进行协调,例如setTimeout
或requestAnimationFrame
或其他。
2.引入RxJS
在我们的真实应用中,我们必须要等到服务器响应后,我们才能获取到数据,因此这天生就需要用异步思维来操作。
由于Angular中已经自带RxJS,所以我们只要在需要使用的时候,引入即可使用:
3.改造数据获取方式
了解完RxJS的一些概念后,我们开始改造下这些书本的数据获取方式。
- 改造
BooksService
首先我们从 RxJS 中导入 Observable
和 of
符号:
// books.service.ts
import { Observable, of } from 'rxjs';
知识点:
Observable
: 观察者模式中的观察者,具体可以参考 Angular修仙之路 RxJS Observable
of
: 用来获取观察者拿到的数据,通常是一个Observable
。
然后修改getBookList
方法
// books.service.ts
getBookList(): Observable<Books[]> {
return of(BookList);
}
这里 of(BookList)
返回一个Observable<Books[]>
,它会发出单个值,这个值就是这些模拟书本的数组。
- 改造
IndexComponent
这里也要修改getBooks
方法,使用subscribe
去订阅服务返回回来的值:
// index.component.ts
getBooks(): void{
this.booksservice.getBookList()
.subscribe(books => this.books = books);
}
由于原本直接赋值数据,在实际场景中是不可能这样同步的,所以这里subscribe
函数,会在Observable
发出数据以后,再把书本列表传到里面的回调函数,再复制给books
属性。
使用这种异步方式,当 BooksService
从远端服务器获取英雄数据时,不用担心还没拿到数据就执行后面。
下一步,我们就要改造一下项目了。
本部分内容到这结束
Author | 王平安 |
---|---|
pingan8787@qq.com | |
博 客 | www.pingan8787.com |
微 信 | pingan8787 |
每日文章推荐 | https://github.com/pingan8787/Leo_Reading/issues |
JS小册 | js.pingan8787.com |
微信公众号 | 前端自习课 |
【CuteJavaScript】Angular6入门项目(3.编写服务和引入RxJS)的更多相关文章
- 【CuteJavaScript】Angular6入门项目(4.改造组件和添加HTTP服务)
本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...
- 【CuteJavaScript】Angular6入门项目(1.构建项目和创建路由)
本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...
- 【CuteJavaScript】Angular6入门项目(2.构建项目页面和组件)
本文目录 一.项目起步 二.编写路由组件 三.编写页面组件 1.编写单一组件 2.模拟数据 3.编写主从组件 四.编写服务 1.为什么需要服务 2.编写服务 五.引入RxJS 1.关于RxJS 2.引 ...
- WCF入门-项目间调用服务
练习WCF入库,添加了一个WCF项目,同时添加了一个控制台程序,在控制台程序启动时,调用WCF服务,报错. 控制台程序代码为: namespace WcfConsumer { class Progra ...
- JAVA WEB快速入门之从编写一个基于SpringBoot+Mybatis快速创建的REST API项目了解SpringBoot、SpringMVC REST API、Mybatis等相关知识
JAVA WEB快速入门系列之前的相关文章如下:(文章全部本人[梦在旅途原创],文中内容可能部份图片.代码参照网上资源) 第一篇:JAVA WEB快速入门之环境搭建 第二篇:JAVA WEB快速入门之 ...
- JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署
接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...
- [转贴]systemd 编写服务管理脚本
[转贴]sparkdev大神的博客, 关于 systemd的配置文件的 介绍, 自己之前二进制安装 k8s 时 超过一个 service文件 但是当时不明不白的. 现在再学习一下大神的文章 的确牛B ...
- SpringCloud学习之手把手教你用IDEA搭建入门项目(三)
本篇博客是承接上一篇<手把手教你用IDEA搭建SpringCloud入门项目(二)>,不清楚的请到我的博客空间查看后再看本篇博客,上面两篇博客成功创建了一个简单的SpringCloud项目 ...
- TensorFlowSharp入门使用C#编写TensorFlow人工智能应用
TensorFlowSharp入门使用C#编写TensorFlow人工智能应用学习. TensorFlow简单介绍 TensorFlow 是谷歌的第二代机器学习系统,按照谷歌所说,在某些基准测试中,T ...
随机推荐
- 如何解决UNMOUNTABLE BOOT VALUME
Windows error:UNMOUNTABLE BOOT VALUME 解决方法:Windows 修复工具 chkdsk命令 chkdsk D:/f ps:chkdsk 磁盘名 /f
- 从壹开始 [ Ids4实战 ] 之六 ║ 统一角色管理(上)
前言 书接上文,咱们在上周,通过一篇<思考> 性质的文章,和很多小伙伴简单的讨论了下,如何统一同步处理角色的问题,众说纷纭,这个我一会儿会在下文详细说到,而且我最终也定稿方案了.所以今天咱 ...
- 选择了uniapp开发app
7月份打算做一简单app,之前公司做app的时候简单用过Dcloud公司的mui,当时由于uniapp刚出来,最终选择了mui.对uniapp的 了解几乎没有. 做app对我来说几乎是零基础的,当然是 ...
- 在centos7上进行hadoop-3.1.2的伪分布搭建
第一步:配置网络(静态IP) vi /etc/sysconfig/network-scripts/ifcfg-ens33(网卡名称可能不同) 1. 修改: 将该配置文件中的ONBOOT=no修改为ye ...
- LAMP架构介绍、MySQL、MariaDB介绍、MySQL安装
5月23日任务 课程内容: 11.1 LAMP架构介绍11.2 MySQL.MariaDB介绍11.3/11.4/11.5 MySQL安装扩展mysql5.5源码编译安装 http://www.ami ...
- 使用Navicat连接阿里云服务器中的Mysql数据库
1.首先将阿里云服务器中的安全组添加上Mysql的端口3306,如下图所示: 步骤就是进入到阿里云的官网,点击右上角控制台,在左边选择云服务器ECS--->实例 点击图中的管理按钮,然后选择本实 ...
- SpringBoot 使用IDEA 配置热部署
在开发中稍微更改一点内容就要重启,很麻烦.这个时候使用Spring Boot的热部署就能解决你的问题. 上图: 1,在pom.xml文件中添加依赖: <dependency> <gr ...
- Linux中docker的使用二
容器下安装jdk和tomcat:通过挂载文件的方法,把宿主机上的文件挂载到容器中,然后解压到opt目录下:tar -zxvf 包名 -C /opt//opt目录下drwxr-xr-x 8 10 143 ...
- 华为云备案服务全面升级,EI助力带来极速体验
华为云备案"电子化核验"正式发布,备案更轻松.更快捷.自2019年9月12日起,华为云用户申请办理ICP备案可以通过华为云APP进行"ICP备案主体真实身份信息采集&qu ...
- gitbook 入门教程之增强版 edit-link-plus 编辑此页插件
Gitbook plugin add "edit this page" link, and intelligent recognition to Github or Gitlab ...