MST
星途 面试题库

面试题:Angular组件间通信的高级方式

除了@Input()、@Output()这种基础的组件间通信方式,Angular还有哪些高级的组件间通信方式?请详细描述每种方式的实现原理和适用场景。
25.6万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

1. 使用 Service 进行通信

  • 实现原理:创建一个共享的服务类,在这个服务中定义数据和方法。不同组件通过注入这个共享服务来访问和修改这些数据,从而实现通信。例如,一个服务中有一个属性 sharedData,组件A可以修改这个属性的值,组件B注入同一个服务实例后,就能获取到修改后的值。
// 共享服务
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class SharedService {
  sharedData: string = '';
}

// 组件A
import { Component } from '@angular/core';
import { SharedService } from './shared.service';

@Component({
  selector: 'app-component-a',
  templateUrl: './component-a.html'
})
export class ComponentA {
  constructor(private sharedService: SharedService) {
    this.sharedService.sharedData = 'Initial data from ComponentA';
  }
}

// 组件B
import { Component } from '@angular/core';
import { SharedService } from './shared.service';

@Component({
  selector: 'app-component-b',
  templateUrl: './component-b.html'
})
export class ComponentB {
  dataFromService: string;
  constructor(private sharedService: SharedService) {
    this.dataFromService = this.sharedService.sharedData;
  }
}
  • 适用场景:适用于兄弟组件间、隔代组件间等复杂关系组件的通信。比如一个电商应用中,商品列表组件和购物车组件可能需要通过共享服务来传递商品添加到购物车等信息。

2. 使用 SubjectBehaviorSubject

  • 实现原理
    • Subject:是一种可观察对象,它可以多播给多个观察者。组件可以将数据发送到Subject,其他订阅了该Subject的组件就会收到通知并获取数据。
    • BehaviorSubject:是Subject的一种变体,它会保存“当前”值,并将这个值发送给新的订阅者。即使在订阅之前数据已经发生了变化,新订阅者也能获取到最新的值。
import { Injectable } from '@angular/core';
import { Subject, BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CommunicationService {
  private subject = new Subject<string>();
  private behaviorSubject = new BehaviorSubject<string>('Initial value');

  sendMessage(message: string) {
    this.subject.next(message);
  }

  getMessage() {
    return this.subject.asObservable();
  }

  sendBehaviorMessage(message: string) {
    this.behaviorSubject.next(message);
  }

  getBehaviorMessage() {
    return this.behaviorSubject.asObservable();
  }
}

在组件中使用:

// 发送数据的组件
import { Component } from '@angular/core';
import { CommunicationService } from './communication.service';

@Component({
  selector: 'app-sender',
  templateUrl: './sender.html'
})
export class SenderComponent {
  constructor(private communicationService: CommunicationService) {
    this.communicationService.sendMessage('Message from Sender');
    this.communicationService.sendBehaviorMessage('Behavior message from Sender');
  }
}

// 接收数据的组件
import { Component } from '@angular/core';
import { CommunicationService } from './communication.service';

@Component({
  selector: 'app-receiver',
  templateUrl: './receiver.html'
})
export class ReceiverComponent {
  message: string;
  behaviorMessage: string;
  constructor(private communicationService: CommunicationService) {
    this.communicationService.getMessage().subscribe(data => {
      this.message = data;
    });
    this.communicationService.getBehaviorMessage().subscribe(data => {
      this.behaviorMessage = data;
    });
  }
}
  • 适用场景
    • Subject:适用于实时事件通知场景,比如实时消息推送,新消息一来就通知相关组件。
    • BehaviorSubject:适用于需要获取最新状态的场景,如应用的主题切换,新进入的组件需要知道当前的主题状态。

3. 使用 Router 传递数据

  • 实现原理:在导航到新路由时,可以通过 state 属性传递数据。新路由组件可以通过 ActivatedRoute 获取这些数据。
// 导航时传递数据
import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-home',
  templateUrl: './home.html'
})
export class HomeComponent {
  constructor(private router: Router) {
    const data = { key: 'value' };
    this.router.navigate(['/destination'], { state: { data } });
  }
}

// 目标路由组件获取数据
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-destination',
  templateUrl: './destination.html'
})
export class DestinationComponent {
  dataFromRoute;
  constructor(private route: ActivatedRoute) {
    this.dataFromRoute = this.route.snapshot.state.data;
  }
}
  • 适用场景:适用于页面跳转时需要携带少量数据的场景,如从商品列表页跳转到商品详情页时,传递商品的基本信息以便详情页加载。