面试题答案
一键面试确定最终使用哪个Provider的规则
- 最近原则:Angular会从组件自身的注入器开始查找Provider。如果在组件注入器中找到了针对该Token的Provider,就使用这个Provider来创建服务实例。
- 向上查找:若组件注入器中没有找到,Angular会沿着注入器树向上一级一级查找,直到根注入器。一旦在某一级注入器中找到对应的Provider,就使用它创建服务实例。如果直到根注入器都没找到,就会抛出错误。
实际应用举例
假设我们有一个应用,在根模块中有一个UserService
的Provider,它提供的是全局的用户信息。
// app.module.ts
import { NgModule } from '@angular/core';
import { UserService } from './user.service';
@NgModule({
providers: [UserService]
})
export class AppModule {}
// user.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class UserService {
user = { name: 'Global User' };
}
然后在某个特性模块的组件中,我们想覆盖全局的UserService
,提供一个特定于该组件的用户信息。
// feature.module.ts
import { NgModule } from '@angular/core';
import { FeatureComponent } from './feature.component';
import { UserService } from './user.service';
@NgModule({
declarations: [FeatureComponent],
providers: [
{
provide: UserService,
useValue: { user: { name: 'Feature User' } }
}
]
})
export class FeatureModule {}
// feature.component.ts
import { Component } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-feature',
templateUrl: './feature.component.html'
})
export class FeatureComponent {
constructor(private userService: UserService) {}
}
在FeatureComponent
中,由于它自身所在模块(FeatureModule
)的注入器中提供了一个针对UserService
的新Provider,所以会使用这个新的Provider,userService.user.name
的值为Feature User
,而不是根注入器中UserService
的Global User
,实现了特定功能。