理解 Angular 服务

本文写于 2021 年 3 月 29 日

什么是服务

angular 的最佳实践推荐业务逻辑要尽量分门别类的抽离为一个个的 Service。

那么到底什么是 Service 呢?

service 意为服务,是一个广义的概念。

例如:饭馆提供的是吃饭服务、澡堂提供的是洗澡服务、学校提供的是授课服务……

那么对于写代码来说,服务是什么呢?

服务一般会包括值/状态、函数或各种特性,在 Angular 中,我们使用一个 class 来包裹这些。

但实际上,服务可以不是一个类,例如 React 的 context,通过闭包得到的返回值也可以是一个服务。

归根结底,可以这么总结:把一系列高度聚合的代码放到一起,就是一个服务

对于前端来说,操心的事情其实有两件:

  1. 用户体验(动画、跳转、样式……)
  2. 业务逻辑与状态管理

Angular 推荐我们将第二点放到服务中来完成,从而令组件可以专心的负责用户体验。

比如从服务器获取数据、验证用户输入、日志……都应该放在服务,而不是特定的组件中。

当我们将这些委托给了各种可注入的服务之后,就可以将其注入到各个组件或者其他服务中进行调用。让你的代码更具适应性。

在 Angular 中,服务通常是一个单例。

服务写法

代码来自 Angular 官方文档,有删改

// 省略 @Injectable 代码
export class Logger {
log(msg: any) {
console.log(msg);
} error(msg: any) {
console.error(msg);
} warn(msg: any) {
console.warn(msg);
}
}

在 ng 组件或是 service 的构造函数中注入服务(框架会帮我们自动完成)后即可在其他方法中调用。

// 省略 @Injectable 代码
export class HeroService {
constructor(private logger: Logger) {} getHeroes() {
this.getXXXXData().then((res: any) => {
this.logger.log(`Fetched data: ${res}`);
});
}
}

原理简述

当 Angular 创建组件类的新实例时,框架会查看该组件类的 constructor,得到该组件依赖哪些服务或其它依赖项。

如果发现了某个组件依赖某个服务,框架会首先检查注入器中是否已经有了那个服务的实例。如果存在,直接返回;如果不存在,注入器就会使用以前注册的服务提供者来创造一个,并把它加入注入器中,最后把该服务返回。

提供服务

服务需要「提供」,才能使用。

1. 在服务中注册

@Injectable({
providedIn: "root",
})
export class SomeService {}

默认情况下,服务会提供给 root,也就是根。这样该服务就可以在任何 module 的组件进行注入。

这种在 @Injectable 元数据中注册提供者的方式还让 Angular 能够通过移除那些从未被用过的服务来优化大小。

2. 在 module 中注册

@NgModule({
providers: [
AService,
BService
],
...
})

你也可以提供给单独的 module,让 service 只能在该 module 使用。

3. 在组件中注册

@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
providers: [ SomeService ]
})

当你在组件级注册提供者时,你会为该组件的每一个新实例提供该服务的一个新实例!!!

所以不推荐这么做。

该在哪里注入服务

Angular 使得我们可以在任何的组件中注入服务,这会使得我们“滥用”注入。

这里我们借用一些 react-redux 中的概念——展示组件和容器组件。

在展示组件中,应该只负责定义自己需要的状态、方法,具体的依赖于外层传入。

在容器组件中,才可以注入服务进行操作。

这样能有效的降低组件对于特定服务的依赖。

(完)

理解 Angular 服务的更多相关文章

  1. (七)理解angular中的module和injector,即依赖注入

    (七)理解angular中的module和injector,即依赖注入 时间:2014-10-10 01:16:54      阅读:63060      评论:1      收藏:0      [点 ...

  2. 理解angular中的module和injector,即依赖注入

    理解angular中的module和injector,即依赖注入 依赖注入(DI)的好处不再赘言,使用过spring框架的都知道.angularjs作为前台js框架,也提供了对DI的支持,这是java ...

  3. angular服务二

    angular服务 $http 实现客户端与服务器端异步请求 get方式 test.html <!DOCTYPE html> <html lang="en"> ...

  4. angular服务一

    angular服务 [$apply()] jquery内数据绑定 要用$apply(),不然不能在js内通过angular绑定数据 <!DOCTYPE html> <html lan ...

  5. angular 服务 service factory provider constant value

    angular服务 服务是对公共代码的抽象,由于依赖注入的要求,服务都是单例的,这样我们才能到处注入它们,而不用去管理它们的生命周期. angular的服务有以下几种类型: 常量(Constant): ...

  6. 第217天:深入理解Angular双向数据绑定的原理

    一.理解angular双向数据绑定 双向绑定是新的前端框架中频繁出现的一个新词汇,也是mvvm的核心原理.angularjs五条核心信念中的数据驱动,便是由双向绑定进行完成. 那么什么是双向绑定,下面 ...

  7. Java生鲜电商平台-深入理解微服务SpringCloud各个组件的关联与架构

    Java生鲜电商平台-深入理解微服务SpringCloud各个组件的关联与架构 概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留 ...

  8. 理解Angular中的$apply()以及$digest()

    $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...

  9. 深入理解Angular中的$Apply()以及$Digest()

    $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...

随机推荐

  1. 学习Tomcat(二)

    一. Java简介 JDK: 面向开发人员使用的SDK,提供Java的开发环境和运行环境 SDK: 软件开发包,包括函数库.编译程序等 JRE: Java的运行环境,面向Java的使用者,不是开发者 ...

  2. 学习Apache(四)

    介绍 Apache HTTP 服务器被设计为一个功能强大,并且灵活的 web 服务器, 可以在很多平台与环境中工作.不同平台和不同的环境往往需要不同 的特性,或可能以不同的方式实现相同的特性最有效率. ...

  3. 第 4 章 ROS运行管理

    第 4 章 ROS运行管理 ROS是多进程(节点)的分布式框架,一个完整的ROS系统实现: 可能包含多台主机:每台主机上又有多个工作空间(workspace):每个的工作空间中又包含多个功能包(pac ...

  4. [源码解析] TensorFlow 分布式环境(7) --- Worker 动态逻辑

    [源码解析] TensorFlow 分布式环境(7) --- Worker 动态逻辑 目录 [源码解析] TensorFlow 分布式环境(7) --- Worker 动态逻辑 1. 概述 1.1 温 ...

  5. ZEGO音视频服务的高可用架构设计与运营

    前言: ZEGO 即构科技作为一家实时音视频的提供商,系统稳定性直接影响用户的主观体验,如何保障服务高可用且用户体验最优是行业面临的挑战,本文结合实际业务场景进行思考,介绍 ZEGO 即构在高可用架构 ...

  6. [译] Facebook:我们是如何构建第一个跨平台的 React Native APP

    英文原文(需FQ):https://code.facebook.com/posts/1189117404435352/ 早些时候,我们介绍过iOS版的React Native. React Nativ ...

  7. 从路由原理出发,深入阅读理解react-router 4.0的源码

      react-router等前端路由的原理大致相同,可以实现无刷新的条件下切换显示不同的页面.路由的本质就是页面的URL发生改变时,页面的显示结果可以根据URL的变化而变化,但是页面不会刷新.通过前 ...

  8. 在 WASI 上运行 .NET 7 应用程序

    WASI代表 WebAssembly 系统接口,WASI 让沙盒化的 WebAssembly 应用程序通过一系列类似 POSIX 的函数访问底层操作系统,允许独立于浏览器运行 WebAssembly ...

  9. Pinpoint介绍及docker安装方式

    一.介绍 Pinpoint是用Java编写的大型分布式系统的APM(Application Performance Management应用程序性能管理)工具,受Dapper论文的启发,Pinpoin ...

  10. Educational Codeforces Round 121 (Rated for Div. 2)——A - Equidistant Letters

    A - Equidistant Letters 题源:https://codeforces.com/contest/1626/problem/A 今天上午VP了这场CF,很遗憾的是一道题也没写出来,原 ...