IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 配置providedIn: ‘root‘ 的angular service 不一定在整个application 层面就是单例服务 -> 正文阅读

[JavaScript知识库]配置providedIn: ‘root‘ 的angular service 不一定在整个application 层面就是单例服务

There are two ways to make a service a singleton in Angular:

  • Set the providedIn property of the @Injectable() to “root”.
  • Include the service in the AppModule or in a module that is only imported by the AppModule

以上是Angular 官网上的原话,说是有两种方法在Angular 应用中提供单例服务,一个是对于可注入的服务配置providedIn: 'root', 二个是只在AppModule 里面引入服务或者只在AppModule 里面引入提供服务的模块。

所以使用示例中完整代码, 发现了不能理解的问题,问题总结下来就是就算配置providedIn: 'root‘, 貌似服务也不是单例的,不管是急性还是惰性加载模块,还需要看看是否在component 里面再次定义了providers。如有问题,欢迎大家指正讨论!

具体执行过程如下:
在这里插入图片描述
app.module.ts 代码如下:

@NgModule({
  imports: [
    BrowserModule,
    ContactModule,
    DevicesModule,
    GreetingModule,  // 注释掉了完整代码中GreetingModule.forRoot 方法的定义
    AppRoutingModule
  ],
  declarations: [
    AppComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts 代码如下:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <app-greeting></app-greeting>
    <nav>
      <a routerLink="devices" routerLinkActive="active">Devices</a>
      <a routerLink="contact" routerLinkActive="active">Contact</a>
      <a routerLink="items" routerLinkActive="active">Items</a>
      <a routerLink="customers" routerLinkActive="active">Customers</a>
    </nav>
    <router-outlet></router-outlet>
  `
})
export class AppComponent {
}

其中Device 和Contact 是急性加载模块,Items 和Customers 是惰性加载模块。
导航下方的形如times 2’s 为注入的UserService.username

user.service.ts 中配置了providedIn: 'root', 需要注意这个是一个重要的配置,这个告知Angular在应用层面提供服务。

import { Injectable, Optional } from '@angular/core';

let nextId = 1;

export class UserServiceConfig {
  userName = 'Philip Marlowe';
}

@Injectable({providedIn: 'root'})
export class UserService {
  id = nextId++;
  
  constructor(@Optional() config?: UserServiceConfig) {
    console.log('user service constructor', config, this.id,);
    if (config) { this._userName = config.userName; }
  }

  get userName() {
    // Demo: add a suffix if this service has been created more than once
    const suffix = this.id > 1 ? ` times ${this.id}` : '';
    return this._userName + suffix;
  }
  private _userName = 'Sherlock Holmes';
}

分别点击Device 和Items, 渲染出来的都是包含Sherlock Holmes times 3's Devices,说明点击Device 的时候重新生成了一个新的UserService实例,并且Items 和 Device 使用的是同一个UserService实例。Device 和Items 相同的配置都是在构造函数中直接引用UserService, 形如:

import { Component } from '@angular/core';
import { UserService } from '../greeting/user.service';

@Component({
  selector: 'app-devices',
  template: `<h2>{{userName}}'s Devices</h2>`,
})
export class DevicesComponent {
  userName = '';

  constructor(private userService: UserService) {
    this.userName = userService.userName;
  }
}

分别点击Contact 和 Customer, 渲染出来的都是Sherlock Holmes times N's, 其中N 是不断上涨的,说明不管点击Contact 还是Customer 都会重新生成新的UserService 实例,而且这俩模块的UserService实例是相互隔离的。Contact和Customer 模块相同的配置都是在@Component装饰器中配置了Providers: [UserService]

import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';

import { Contact, ContactService } from './contact.service';
import { UserService } from '../greeting/user.service';

@Component({
  selector: 'app-contact',
  template: `<h2>{{userName}}'s Contacts</h2>`,
  styleUrls: [ './contact.component.css' ],
  providers: [UserService]
})
export class ContactComponent implements OnInit {
  userName = '';

  constructor(private contactService: ContactService, userService: UserService) {
    this.userName = userService.userName;
  }
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:02:06  更:2022-04-04 12:06:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:01:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码