angular 单例
默认情况下,Angular CLI 命令 ng generate service
会通过给 @Injectable()
装饰器添加 providedIn: 'root'
元数据的形式,用根注入器将你的服务注册成为提供者。
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class HeroService {
constructor() { }
}
当你在顶层提供该服务时,Angular 就会为 HeroService
创建一个单一的、共享的实例,并把它注入到任何想要它的类上。
在 @Injectable
元数据中注册该提供者,还能允许 Angular 通过移除那些完全没有用过的服务来进行优化。
缺点:Service
比较灵活,可以存放数据,但是数据是公开出去的,难免会不轻易间就在组件中直接操作 Service
中的数据了
代码在 https://github.com/lintingying/angular-lin/tree/main/main/src/app/core/init
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class Config { BaseUrl: string;
}
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { NzMessageService } from 'ng-zorro-antd/message'; import { Config } from './config'; /** * 用于应用启动时 * 获取应用基础数据 */ @Injectable({ providedIn: 'root', }) export class StartService { constructor(private http: HttpClient, private messageSvc: NzMessageService, private config: Config) { } load(): Promise<any> { return new Promise((resolve, reject) => { this.http.get('/assets/config/config.json').subscribe((res: Config) => { this.config.BaseUrl = res.BaseUrl; this.config.MicroApps = res.MicroApps; resolve(res); }, (err: HttpErrorResponse) => { this.messageSvc.error('加载服务器信息失败,API服务不可用'); }); }); } }
angular 多例
在组件树的同一个级别上,有时需要一个服务的多个实例。
每个组件都需要该服务的单独实例。 每个服务有自己的工作状态,与其它组件的服务和状态隔离。这叫做沙箱化,因为每个服务和组件实例都在自己的沙箱里运行。
通过在自己的元数据(metadata)providers
数组里面列出Service
, 这样每个 Component
就能拥有自己独立的Service
实例了
@Component({
selector: 'app-hero',
template: ``,
providers: [HeroService]
})
export class HeroComponent implements OnInit {
constructor(private heroSvc: HeroService) { }
ngOnInit() { }
}
forRoot() 模式
通常,你只需要用 providedIn
提供服务,用 forRoot()
/forChild()
提供路由即可。
如果模块同时定义了 providers(服务)和 declarations(组件、指令、管道),那么,当你同时在多个特性模块中加载此模块时,这些服务就会被注册在多个地方。这会导致出现多个服务实例,并且该服务的行为不再像单例一样。
有多种方式来防止这种现象:
-
用
providedIn
语法代替在模块中注册服务的方式。 -
把你的服务分离到它们自己的模块中。
-
在模块中分别定义
forRoot()
和forChild()
方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通