Angular7入门辅助教程(九)——单例服务

如果有任何的非技术障碍,比如如何新建Angular项目,请先到我的"Angular7入门辅助教程"专栏参考这篇博客:Angular7入门辅助教程——前篇

通过前两章关于服务的基础知识的学习,我想你应该对Angular中的服务有一个大致的了解,但是,如果我猜的没错的话:在实际应用中,你应该还不会使用服务(如果不信,看看你自己是否能不在我的帮助下面自己敲出本章的所有实例!),因为前面两章都只在说服务服务,却没有谈到服务实例,而在实际应用中,我们使用的都是服务的实例(你必须清楚自己到底使用的是哪个服务的哪个实例!),也就是说,前两章是Angular服务的理论层面,是基础,而这一章是应用层面,是前两章的总结,是升华,所以,本章节包含大量的实例!而且会引入一个核心知识点——注入器,本章的所有的东西都是围绕这个概念进行

心法篇

  • 在你使用服务之前,你必须先将该服务提供给Angular的依赖注入系统,我们需要一个注入器对象来注册提供商,注入器负责在需要时选取和注入提供商,而提供商负责提供和交付需要的服务实例
  • 单例服务,顾名思义,就是只有一个服务实例,无论你在什么地方注入该服务,使用的都是同一个服务的实例
  • Angular中有一个注入器的概念,前面提到,服务提供商是用来告诉Angular如何查找服务以及如何提供服务实例,而注入器是用来保存服务提供商以及服务实例,你不用自己建立注入器,Angular会帮你完成(将注入器想象成一个注射器,里面有服务实例,这个注射器会在用到该服务的地方将服务实例注入,这样是不是好理解一些)
  • 是否记得前面提到过三种级别的服务,对应三种级别的服务作用域,我说过,使用作用域不太准确,在这一节,替换成注入器,因此,三种级别的服务分部对应应用级注入器、普通模块级注入器(为什么加上普通两个字呢?是为了和AppModule区分开来)、组件级注入器,
  • 服务在这里不再指带有@Injectable装饰器的服务了,而是广义的服务,所有你想用到的东西都可以当做服务来使用,结合这三章,你就可以随心所欲的使用服务了
  • Angular趋向于使用已经存在的服务实例,而不是新建
  • 在Angular中,存在一个与组件树平行的注入器树!!!!
  • Angular会优先使用自己本级别的注入器中的服务实例,如果在自己的注入器中没有找到相应的服务实例,就会去父级注入器(包括父组件注入器,模块级注入器)中找,直到超出根注入器——这叫注入器冒泡,如果不做处理的话,Angular就会报错

心法篇中有两点极其重要,我单独拉出来在说一遍

  • 在Angular中,存在一个与组件树平行的注入器树!!!!
  • 如果在自己的注入器中没有找到相应的服务实例,就会去父级注入器(包括父组件注入器,模块级注入器)中找,直到超出根注入器——这叫注入器冒泡,如果不做处理的话,Angular就会报错

这些内容如果是首次接触,有点难懂,没关系,所有的这些知识,在本章我都会通过实例的方式来讲解

详细教程篇

1、单例服务

说到底,本章的重点是如何建一个在某范围使用的单例服务,以及如何正确使用它,所以我将本章的标题命名为单例服务,那么,在Angular中,单例服务是如何体现的呢?

  • 创建应用级别的单例服务

很简单,你应该都能猜到,应用级别的服务,也就是在AppModule中提供的服务,

即有两种方式:1、设置服务元数据对象providedIn:'root',以及2、在AppModule元数据对象providers中指定相应的提供商,

但是,注意重点来了:这个服务提供商你不能再次写在其他的惰性加载模块(这个概念不作要求)的元数据对象的providers或者组件的元数据的providers,如果你这样做了,Angular会新建一个服务实例,并注入到本级别的注入器中,这样,这个服务就不再是单例的了!(请继续往下看)

  • 创建模块级别的单例服务

该服务的一个实例可以在本模块的任何地方被使用!,创建方式也有两种(同创建模块级别的服务),但是,注意重点来了,同样的,你也不能在别的地方再配置一遍该服务提供商,例如:该模块中的组件元数据对象的providers中,否则,该服务又不再是单例

  • 创建组件级别的单例服务

该服务的一个实例能在该组件以及其子组件中使用,创建方式只有一种(同创建组件级别的服务),就是在组件的元数据中配置服务提供商

2、单例服务出顾茅庐

下面我们来看一个同属于一个模块下面的两个不同的组件使用同一个应用级别的服务

(这些基础的命令在后面的例子中就不再写了)

1)、新建项目名叫test-teaching-a,并cd进该目录

ng new test-teaching-a

2)、新建一个组件,名叫parent的组件

ng generate component parent

3)、新建一个名叫logger的服务

ng generate service logger

4)、将app.component.html内容替换成下面这个

<h1>{
  
  { title }}</h1>
<ul>
  <li *ngFor="let log of loggerService.getLogges()">{
  
  { log }}</li>
</ul>
<button (click)="addLog()">AddLog</button>
<hr />
<app-parent></app-parent>

5)、将app.component.ts内容替换成下面这个

import { Component } from '@angular/core';
import { LoggerService } from './logger.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'test-teaching-a';

  constructor(private log
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值