面试题答案
一键面试根作用域
- 工作原理:根作用域是应用级别的作用域,整个应用只有一个根注入器。所有在根作用域注册的服务,在整个应用中是单例的。无论在应用的哪个组件中注入该服务,都将获得同一个实例。
- 对服务实例化的影响:
- 创建新实例:当应用启动,首次有组件尝试注入在根作用域注册的服务时,会创建该服务的新实例。
- 复用已有实例:后续任何组件注入该服务,都会复用启动时创建的那个实例。
- 代码示例:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class RootScopedService {
private data: string = 'Initial data in root scoped service';
getData() {
return this.data;
}
setData(newData: string) {
this.data = newData;
}
}
在组件中使用:
import { Component } from '@angular/core';
import { RootScopedService } from './root - scoped.service';
@Component({
selector: 'app - root',
templateUrl: './app.component.html'
})
export class AppComponent {
constructor(private rootScopedService: RootScopedService) {
console.log(this.rootScopedService.getData());
this.rootScopedService.setData('New data in app component');
}
}
在另一个组件中:
import { Component } from '@angular/core';
import { RootScopedService } from './root - scoped.service';
@Component({
selector: 'app - another - component',
templateUrl: './another - component.html'
})
export class AnotherComponent {
constructor(private rootScopedService: RootScopedService) {
console.log(this.rootScopedService.getData()); // 会输出 'New data in app component'
}
}
组件作用域
- 工作原理:每个组件都有自己的注入器,组件作用域的服务仅在该组件及其子组件内有效。如果一个服务在组件中注册,那么这个组件及其子组件会创建和使用该服务的独立实例,与其他组件使用的实例相互隔离。
- 对服务实例化的影响:
- 创建新实例:当组件初始化且首次尝试注入在该组件作用域注册的服务时,会创建新实例。
- 复用已有实例:在该组件及其子组件内,后续注入该服务会复用这个组件作用域内创建的实例。但与其他组件的同类型服务实例不共享。
- 代码示例:
import { Injectable } from '@angular/core';
@Injectable()
export class ComponentScopedService {
private data: string = 'Initial data in component scoped service';
getData() {
return this.data;
}
setData(newData: string) {
this.data = newData;
}
}
在组件中注册并使用:
import { Component } from '@angular/core';
import { ComponentScopedService } from './component - scoped.service';
@Component({
selector: 'app - component - scope - demo',
templateUrl: './component - scope - demo.html',
providers: [ComponentScopedService]
})
export class ComponentScopeDemoComponent {
constructor(private componentScopedService: ComponentScopedService) {
console.log(this.componentScopedService.getData());
this.componentScopedService.setData('New data in component - scope - demo component');
}
}
在子组件中:
import { Component } from '@angular/core';
import { ComponentScopedService } from './component - scoped.service';
@Component({
selector: 'app - sub - component',
templateUrl: './sub - component.html'
})
export class SubComponent {
constructor(private componentScopedService: ComponentScopedService) {
console.log(this.componentScopedService.getData()); // 会输出 'New data in component - scope - demo component'
}
}
如果在另一个组件中使用同样的 ComponentScopedService
,由于不在同一个组件作用域,会创建新的实例,与 ComponentScopeDemoComponent
中的实例相互独立。