angular 服务详谈

一, 服务的简单使用


0.概括
主要是四步: 创建导入声明(配置)注入

1. 创建服务
使用cli 命令: ng g s t1创建一个 名叫 t1 的服务

在这里插入图片描述
2.导入(在需要使用该服务的组件内导入)
在这里插入图片描述
3.声明(这步操作在使用命令行新建服务文件时,已经默认配置了。可以根据自己的需要进行修改)(ng6+ 版会这样,ng4则不会这样)
在这里插入图片描述
4.注入(在需要使用该服务的组件的 构造器中导入)
在这里插入图片描述

二, 服务的声明详谈

接下来讨论的内容主要是 服务使用步骤的第三步,声明(配置) 服务 的相关内容

1. 什么是服务的声明(what)

在js中使用一个变量,正常的步骤就是先使用var声明。ng的服务也是,我们在组件中使用的是服务的实例。在上面说的服务使用四个步骤也可以理解为:① 创建一个类 ②导入这个类 ③实例化这个类 ④注入使用这个类的实例。
声明 = 用服务商(providers) 来配置注入器 = 创建依赖项的实例 = 要求注入器从类去创建对象/实例 = 配置providers(服务提供商)
在这里插入图片描述
2. 在哪里可以进行 服务的声明(where)

服务可以在3个位置被声明 (即配置服务提供商providers的3个地方—服务模块组件

2.1 在 装饰器 @Injectable 中的元数据的配置项中 (provideIn)(即使用 cli 创建的服务默认的)
在这里插入图片描述

2.2 在装饰器 @NgModule 中的元数据的配置项中 (providers) (需要在模块中先导入服务)
在这里插入图片描述
在这里插入图片描述
2.3 在装饰器 @Component 中的元数据的配置项中 (providers) (需要在模块中先导入服务)
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
      2.3.1 和前2个配置位置不同的是,在组件内声明服务,可以起到 数据隔离 的作用。虽然ng里面的服务是单例化的,但是每一次声明(配置)就是对服务类的一次新的实例化。
       在组件里面配置providers,是对依赖项值(无论依赖项是类,字符串还是对象)的多份copy,保证每一个配置providers的组件拥有一份独立依赖项的值,各个组件对自己拥有的 依赖项的值进行修改,互不影响。

       下图中 test1 和 test2 是2个 同属于一个模块的直系 兄弟组件,他们都引用了 t1 服务,但是 test1 组件里面的t1 服务 和 tets2 里面的t1 服务是2个 不同的实例服务 , 2个服务之间的数据互不影响 。
在这里插入图片描述
      2.3.2 在组件内声明服务,可以起到 数据隔离 的作用的同时,也会产生 向上冒泡(即子组件在构造器里面注入的服务,并没有在该子组件中配置,子组件不会报错,而是向上寻找父组件是否声明了该服务)。
       下图中,test2 组件 使用了t2 服务,但是该组件中只声明了t1服务。
在这里插入图片描述
       即便如此也不会报错,因为test2的父组件声明了t2服务,如果是所有的父组件中都没有声明该服务,则会报错。
在这里插入图片描述
      2.3.3 在ng2+ 里面是 没有$on 和 $emit 的,那么如何实现 兄弟组件非直系 父子组件之间 的 通信。 直系父子组件可以通过@input,@ouput 或者模板变量实现通信,但是层级比较多的情况下则比较麻烦。 思路: 可以通过2.3.2 里面的 向上冒泡 和 单例化来实现。 (即父子组件或兄弟组件,共用父组件的同一个实例化服务)
      如图 父组件 app 和 子组件 tets2 共用一个t2 服务,从而实现数据共享,方法共享,实现通信
在这里插入图片描述
3. 如何进行 服务的声明(how)
服务的声明并非只有 provides:[T2Service]这一种方式,根据providers 的类别不同,有不同的provides配置方式(即不同的服务实例声明方式)
服务提供商(providers)大概分为 类提供商(又分为四小类)非类提供商(包括 字符串、函数或对象等) 和 工厂提供商 3类
       3.1.1 类提供商 – 类提供商 (这是注入服务类实例的最简单的方法 — 即new 出这个类的实例) ( useClass
在这里插入图片描述
              这种providers一维 数组是一种简写 ,全写如下: [{ 令牌服务 提供商定义的对象 }] (令牌即token)
在这里插入图片描述
       3.1.2 类提供商 – 带有依赖项的类提供商useClass
       当 一个服务A去依赖另一个服务B的时候,不需要在服务A中去特意配置服务B。只需要在使用服务A的组件中,去同时配置服务A和B就可以了。
       下图中app组件 引用注入了服务类t2,同时服务类t2内部使用了 服务类t1,但是并没有在服务器类t2中引入 服务类t1,而是在app组件 同时引入了 服务类t1和服务类 t2
在这里插入图片描述
       3.1.3 类提供商 – 替代类提供商useClass
      当组件使用T1 服务令牌时,给它返回一个 T2服务 实例。场景:①之前的大部分组件都使用的是T1 服务,但是单独就 app这个旧组件,想更换为新的服务T2
在这里插入图片描述
       3.1.4 类提供商 – 别名类提供商useExisting) (和3.1.3 的替代类提供商差不多) 。但是useExitsing 使用的服务也需要注入。
在这里插入图片描述
       3.2.1 非 类提供商 – 非类提供商useValue) (并非所有的 依赖项 都是类 ,也可以是字符串、函数或对象/类的实例 等 )
在这里插入图片描述
       上图中虽然实现了依赖项是 非类,但是使用的令牌却是类的,如何让非类依赖项 拥有自己的令牌呢? (借助InjectionToken 对象
在这里插入图片描述
       非类提供商的实用场景:统一的配置项或多处使用的常量。(单纯的 export + import 也可以实现相同的功效)
(OpaqueToken 在ng4里面被弃用,使用InjectionToken代替),demo:
在这里插入图片描述
       3.3 工厂提供商 – 工厂提供商useFactory) ( 使用一个回调函数,根据当前的提供商,动态返回其它其它提供商或处理过的提供商 )
在这里插入图片描述
hero 服务 经过useFactory处理,虽然返回的还是hero 服务。但是直接通过hero 服务,调用getHeroes方法 和 通过使用useFactory处理的hero 服务,调用getHeroes方法 ,返回的数据是不一样的
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值