面试题答案
一键面试1. 设计属性绑定架构
- 单一数据源原则:将共享数据放在服务中管理,组件通过依赖注入获取服务实例来访问数据。这样可以确保数据的一致性,并且便于维护和扩展。
// 数据服务 import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class SharedDataService { private data: any; setData(newData: any) { this.data = newData; } getData() { return this.data; } } // 使用服务的组件 import { Component, OnInit } from '@angular/core'; import { SharedDataService } from './shared-data.service'; @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'] }) export class ChildComponent implements OnInit { dataFromService: any; constructor(private sharedDataService: SharedDataService) {} ngOnInit() { this.dataFromService = this.sharedDataService.getData(); } }
- 输入属性(@Input())传递:对于父子组件之间的属性传递,使用
@Input()
装饰器。在父组件模板中设置子组件的输入属性值。<!-- 父组件模板 --> <app-child [inputProperty]="parentData"></app-child> <!-- 子组件 --> import { Component, Input } from '@angular/core'; @Component({ selector: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.css'] }) export class ChildComponent { @Input() inputProperty: any; }
- 跨多层组件传递属性(ViewProviders和InjectionTokens):使用
ViewProviders
和InjectionTokens
来实现跨多层组件传递属性。import { InjectionToken } from '@angular/core'; export const MY_TOKEN = new InjectionToken<string>('myToken'); // 高层组件 import { Component } from '@angular/core'; @Component({ selector: 'app-parent', templateUrl: './parent.component.html', viewProviders: [ { provide: MY_TOKEN, useValue: 'data to be passed' } ] }) export class ParentComponent {} // 深层子组件 import { Component, Inject } from '@angular/core'; @Component({ selector: 'app-deep - child', templateUrl: './deep - child.component.html' }) export class DeepChildComponent { constructor(@Inject(MY_TOKEN) public data: string) {} }
2. 设计事件绑定架构
- 输出属性(@Output())和事件发射器(EventEmitter):子组件通过
@Output()
和EventEmitter
来发出事件,父组件在模板中监听该事件。// 子组件 import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app - child', templateUrl: './child.component.html' }) export class ChildComponent { @Output() customEvent = new EventEmitter(); triggerEvent() { this.customEvent.emit('event data'); } } <!-- 父组件模板 --> <app - child (customEvent)="handleChildEvent($event)"></app - child>
- 事件冒泡处理:利用
@Output()
可以模拟事件冒泡。子组件发出事件,父组件捕获后可以选择继续向上传递。// 子组件 import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app - grand - child', templateUrl: './grand - child.component.html' }) export class GrandChildComponent { @Output() grandChildEvent = new EventEmitter(); triggerGrandChildEvent() { this.grandChildEvent.emit('grand child event data'); } } // 中间组件 import { Component, Output, EventEmitter, Input } from '@angular/core'; @Component({ selector: 'app - child', templateUrl: './child.component.html' }) export class ChildComponent { @Output() childEvent = new EventEmitter(); @Input() grandChildEvent: any; ngOnInit() { this.grandChildEvent.subscribe((data) => { this.childEvent.emit(data); }); } } <!-- 父组件模板 --> <app - child (childEvent)="handleChildEvent($event)"> <app - grand - child (grandChildEvent)="childComponent.grandChildEvent"></app - grand - child> </app - child>
3. 利用变更检测机制优化性能
- OnPush策略:对于一些纯展示组件,使用
ChangeDetectionStrategy.OnPush
策略。当组件的输入属性引用不变或者有新的事件从该组件或者其后代组件触发时,才会触发变更检测。import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app - on - push - component', templateUrl: './on - push - component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class OnPushComponent { @Input() data: any; }
- 不可变数据:使用不可变数据模式,每次数据变化时返回新的对象或数组,这样Angular的变更检测机制可以更高效地检测到变化。
import { Component } from '@angular/core'; @Component({ selector: 'app - immutable - data - component', templateUrl: './immutable - data - component.html' }) export class ImmutableDataComponent { data = [1, 2, 3]; updateData() { this.data = [...this.data, 4]; } }
通过以上架构设计和优化策略,可以在大型Angular企业级应用中有效地管理属性绑定和事件绑定,提高应用的可维护性、性能和扩展性。