服务的概念
服务并没有一个明确的定义,在 Angular 的应用中,比较推荐的做法是,把诸如从服务器获取数据、验证用户输入等工作委托给各种服务,而组件主要用于提供有关绑定数据到模板的属性和方法。
将组件和服务分开,可以有效提高代码的复用性。
依赖注入的概念
依赖注入不是一种技术,而是一种编程思想,能够帮助开发者设计出松耦合、可扩展、便于复用的系统。
所谓依赖,在 Angular 中,主要指服务,通过把各种服务配置到(注入的过程)模块或组件中,来共同完成业务逻辑。
创建服务
下面是已经创建好的服务文件 login.service.ts:
例子:
// 引入装饰器 Injectable
import { Injectable } from '@angular/core';
// providedIn:将服务注入到组件或模块中
// 默认值为 root,即注入到根模块,整个应用都可以访问
@Injectable({
providedIn: 'root'
})
export class LoginService {
constructor() { }
// 添加一个方法
getName(){
return 'Tom';
}
}
下图是从宏观上观察一下服务与组件、子路由、特性模块之间的关系:
注入服务
注入服务大致可以分为以下三种形式:
1、注入到根模块
例子:
服务文件:login.service.ts
import { Injectable } from '@angular/core';
// 将服务注入到根模块
// 整个应用都可以访问到
@Injectable({
providedIn: 'root'
})
export class LoginService {
constructor() { }
getName(){
return 'Tom';
}
}
使用服务的组件:login.component.ts
import { Component, OnInit } from '@angular/core';
// 导入服务
import { LoginService } from '../service/login.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
// 此处非常重要
// 在构造函数中声明 LoginService 服务
constructor(
private loginService:LoginService,
) { }
ngOnInit() {
// 使用 LoginService 服务
console.log(this.loginService.getName());
}
}
2、注入到特性模块
例子:
服务文件:login.service.ts
import { Injectable } from '@angular/core';
// 将 providedIn: 'root' 删除
@Injectable()
export class LoginService {
constructor() { }
getName(){
return 'Tom';
}
}
在特性模块中注入需要的服务:login.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginRoutes, Components } from './login.routing';
// 在特性模块中导入服务
import { LoginService } from './service/login.service';
@NgModule({
imports: [
CommonModule,
LoginRoutes
],
declarations: [...Components],
// 在 providers 中注入 LoginService
providers: [
LoginService
],
})
export class LoginModule { }
使用服务的组件:login.component.ts
import { Component, OnInit } from '@angular/core';
// 导入服务
import { LoginService } from '../service/login.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
// 此处非常重要
// 在构造函数中声明 LoginService 服务
constructor(
private loginService:LoginService,
) { }
ngOnInit() {
// 使用 LoginService 服务
console.log(this.loginService.getName());
}
}
3、注入到组件
例子:
服务文件:login.service.ts
import { Injectable } from '@angular/core';
// 将 providedIn: 'root' 删除
@Injectable()
export class LoginService {
constructor() { }
getName(){
return 'Tom';
}
}
直接在组件中注入需要的服务:login.component.ts
import { Component, OnInit } from '@angular/core';
// 导入服务
import { LoginService } from '../service/login.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
// 在 providers 中注入 LoginService 服务
providers: [
LoginService
],
})
export class LoginComponent implements OnInit {
// 此处非常重要
// 在构造函数中声明 LoginService 服务
constructor(
private loginService:LoginService,
) { }
ngOnInit() {
// 使用 LoginService 服务
console.log(this.loginService.getName());
}
}
服务的作用域
通常情况下,注入到根模块中的服务,是整个 Angular 应用都需要的服务,具有全局作用域;
而注入到特性模块中的服务,只能为这个模块下的所有组件提供服务;
如果是在组件中注入服务,那么只会在该组件及其子组件中有效,同一模块中的其它组件无法访问。
在服务中引用其他服务
与在组件中使用服务的模式相同。
例子:
需要引入其他服务的服务文件:login.service.ts
import { Injectable } from '@angular/core';
// 导入 ApiService 服务
import { ApiService } from '../../common/api.service';
@Injectable()
export class LoginService {
constructor(
// 声明 ApiService 服务
private api:ApiService
) { }
getName(){
// 使用 ApiService 服务
return this.api.getJson();
}
}
end