服务

angular中,组件之间不能相互调用。可以把公共部分封装成服务,然后在组件中调用服务。

  • 所有的组件都可以调用服务;

  • 服务不能调用组件;

  • 组件之间也不能相互调用组件的方法;

  • 组件之间可以父子组件传值;

  • 服务和服务之间可以相互调用;

创建服务

  1. 在src/app下创建services文件夹,并在该文件夹中创建storage服务

    创建组件时,如果使用 ng g component compoents/search ,会创建components文件夹后,再在文件夹内创建search文件夹来存放组件;

创建服务时,使用 ng g service services/storage ,会创建services文件夹后,直接在services文件夹中生成服务的程序

  1. ng g service services/storage


新增的服务包含以下文件:

  • xxx.service.ts 服务的ts文件
  • xxx.service.spec.ts 测试文件,可删除
  1. import { Injectable } from '@angular/core';
  2. // 要把一个类定义为服务,需要使用@Injectable装饰器来提供元数据,以便让Angular可以把它作为依赖注入到组件中。
  3. // 服务可以把自己的元数据注册为提供者,这样可以让自己随处可用。或者,你也可以为特定的模块或组件注册提供者。
  4. // 要注册提供者,就要在服务的@Injectable()装饰器中提供他的元数据,或者在@NgModule()或@Component()的元数据providers数组中。
  5. // 默认情况下,angular CLI的 `ng generate service` 命令会在@Injectable()装饰器中提供元数据来把它注册到根注入器中: providedIn: 'root'
  6. // 当你在根一级提供服务时,该服务为单例。这种在@Injectable元数据中注册提供者的方式还让Angular能够通过移除那些从未被用过的服务来优化大小
  7. // 当在特定NgModule中,使用@NgMoudle中的providers属性注册提供者时,该服务的同一个实例对该NgModule的所有组件可用
  8. // 当在特定Component中,使用@Component的providers属性注册提供者时,会为该组件的每一个新实例提供一个服务新实例。
  9. @Injectable({
  10. providedIn: 'root'
  11. })
  12. export class StorageService {
  13. constructor() { }
  14. // 编写逻辑
  15. get() {
  16. return 'test service';
  17. }
  18. }
  1. 在app.module.ts中加入该服务 ```typescript // 使用import引入服务 import { StorageService } from ‘./services/storage.service’

// declarations可声明对象表: 属于本NgModule的组件、指令、管道 // imports: 导入本模块中的组件模板所需的类的其他模块 // providers: 本模块向全局服务中贡献的服务的创造器,这些服务能被本应用中的任务部分使用(也可以在组件级别指定服务提供者,通常指定组件级别) // bootstrap: 应用的主视图,根组件。它是应用中所有其他视图的宿主。只有根模块才应该设置bootstrap属性 @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FormsModule ], // 在@NgModule的providers中添加服务 providers: [StorageService], bootstrap: [AppComponent] }) export class AppModule { }

  1. <a name="57efd3db"></a>
  2. ## 使用服务方式1(不推荐)
  3. > 在要编辑的模块中,引入服务,将服务暴露的class实例化出来一个对象
  4. 示例:在todolist模块中引入storage服务,编辑todolist.components.ts
  5. ```typescript
  6. import { Component, OnInit } from '@angular/core';
  7. // 引入服务
  8. import { StorageService } from '../../services/storage.service'
  9. // 将服务的class实例化出一个对象
  10. let storageService = new StorageService();
  11. @Component({
  12. selector: 'app-todolist',
  13. templateUrl: './todolist.component.html',
  14. styleUrls: ['./todolist.component.css']
  15. })
  16. export class TodolistComponent implements OnInit {
  17. // 在构造方法中使用该对象
  18. constructor() {
  19. let s = storageService.get();
  20. console.log(s);
  21. }
  22. }

使用服务方式2

在构造方法中使用依赖注入

示例:在todolist模块中引入storage服务,编辑todolist.components.ts

  1. import { Component, OnInit } from '@angular/core';
  2. // 引入服务
  3. import { StorageService } from '../../services/storage.service'
  4. @Component({
  5. selector: 'app-todolist',
  6. templateUrl: './todolist.component.html',
  7. styleUrls: ['./todolist.component.css']
  8. })
  9. export class TodolistComponent implements OnInit {
  10. // 在构造方法中自动注入对象(不加public时,为constructor的方法内部变量。加了public为class的变量,可在class中任意地方使用this.storageService调用)
  11. constructor(public storageService: StorageService) {
  12. let s = this.storageService.get();
  13. console.log(s);
  14. }
  15. }