angular-服务

作者: 姜治宇 | 来源:发表于2020-11-16 23:13 被阅读0次

    按照传统设计理念,在组件(component)中不应该直接获取或保存数据, 组件应该聚焦于展示数据,而把数据访问的职责委托给服务(service)。
    因此,服务就充当着数据访问、逻辑处理的功能。
    一般来讲,service都应该设计成单例模式,注入到全局以便给各个组件提供服务;但如果某些service只给特定一个组件或几个组件提供服务,那注入到全局就没啥必要了,我们可以只在特定组件里面注入使用即可,用个形象点的比喻就是大众服务(单例)和特定服务(多个实例)。
    下面看一下两种的实现。

    单例服务

    我们创建2个service和2个component:

    ng g component components/news
    ng g component components/prod
    
    ng g service services/common //大众服务
    ng g service services/spec //特定服务
    

    common.service.ts:

    import { Injectable } from '@angular/core';
    
    @Injectable({
      providedIn: 'root' // 如果是全局单例,可以注入到根组件
    })
    export class CommonService {
      random:string;
      constructor() { 
        this.random = Math.random().toFixed(2);
      }
    }
    

    在服务里面,我声明了一个随机数,然后分别在两个组件中调用这个服务,如果随机数不变,那就是单例。
    news.components.ts:

    import { Component, OnInit } from '@angular/core';
    import { CommonService } from '../../services/common.service';
    @Component({
      selector: 'app-news',
      templateUrl: './news.component.html',
      styleUrls: ['./news.component.css']
    })
    export class NewsComponent implements OnInit {
    
      constructor(commonService:CommonService) {
        console.log(commonService.random)
       }
    
      ngOnInit(): void {
      }
    
    }
    
    

    prod.components.ts:

    import { Component, OnInit } from '@angular/core';
    import { CommonService } from '../../services/common.service';
    @Component({
      selector: 'app-prod',
      templateUrl: './prod.component.html',
      styleUrls: ['./prod.component.css']
    
    })
    export class ProdComponent implements OnInit {
    
      constructor(commonService:CommonService) {
        console.log(commonService.random)
       }
    
    
      ngOnInit(): void {
      }
    
    }
    
    

    这样news组件和prod组件就可以共享commonService单例服务了。
    当然,service也可以在module里面注入,比如在app.module.ts中注入:

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { NewsComponent } from './components/news/news.component';
    import { ProdComponent } from './components/prod/prod.component';
    import { CommonService } from './services/common.service'
    @NgModule({
      declarations: [
        AppComponent,
        NewsComponent,
        ProdComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule
      ],
      providers: [CommonService], //在模块中注入service
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    注入root根组件或者注入app.module其实都一样,二者选其一即可。

    特定服务

    如果是特定服务那就容易了,只需在使用到的component内部声明即可。
    spec.service.ts:

    import { Injectable } from '@angular/core';
    
    @Injectable() //这里不需声明注入到哪里
    export class SpecService {
    
      random:string;
      constructor() { 
        this.random = Math.random().toFixed(2);
      }
    }
    

    news.components.ts:

    import { Component, OnInit } from '@angular/core';
    import { SpecService } from '../../services/spec.service';
    @Component({
      selector: 'app-news',
      templateUrl: './news.component.html',
      styleUrls: ['./news.component.css'],
      providers:[SpecService] //组件内部声明service
    })
    export class NewsComponent implements OnInit {
    
      constructor(specService:SpecService) {
        console.log(specService.random)
       }
    
      ngOnInit(): void {
      }
    
    }
    
    

    prod.components.ts:

    import { Component, OnInit } from '@angular/core';
    import { SpecService } from '../../services/spec.service';
    @Component({
      selector: 'app-prod',
      templateUrl: './prod.component.html',
      styleUrls: ['./prod.component.css'],
      providers:[SpecService]//组件内部声明service
    
    })
    export class ProdComponent implements OnInit {
    
      constructor(specService:SpecService) {
        console.log(specService.random)
       }
    
      ngOnInit(): void {
      }
    
    }
    
    

    测试发现news组件和prod组件打印的随机数不一致,说明service起了两个实例。
    这里需要注意的是——服务必须指定注入地点。无论你是注入到组件也好模块也罢,必须要指定。
    如上例,如果不在news组件或prod组件的修饰器@Component()里面注入,服务本身也没指定注入到root根组件,也没在app.module下注入,那就会报错,在使用服务时一定要注意哈~~

    相关文章

      网友评论

        本文标题:angular-服务

        本文链接:https://www.haomeiwen.com/subject/nzktiktx.html