📅  最后修改于: 2023-12-03 15:08:51.606000             🧑  作者: Mango
在 Angular 中,组件间的数据传递通常是通过 @Input 和 @Output 装饰器实现的。其中,@Input 装饰器将一个属性声明为可从父组件绑定的输入属性,而 @Output 装饰器则将一个属性声明为一个可以从子组件触发的输出事件。
假设有如下两个组件:parent 和 child。
// parent.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: '<app-child [message]="parentMessage"></app-child>',
})
export class ParentComponent {
parentMessage = 'message from parent';
}
// child.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
template: '<h2>{{message}}</h2>',
})
export class ChildComponent {
@Input() message: string;
}
在 parent 组件中,通过将 message 绑定到 [message] 属性上,将数据从父组件传递给了 child 组件。
在 child 组件中,通过在属性声明前添加 @Input() 装饰器,将该属性声明为一个可接受从父级组件传递而来的输入属性。
假设现在需要将一些状态从 child 组件传递给 parent 组件。此时可以使用 @Output 装饰器来定义一个 EventEmitter,并将其作为输出属性输出。
// child.component.ts
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<button (click)="sendMessage()">Send Message</button>
`,
})
export class ChildComponent {
message = 'message from child';
@Output() messageEvent = new EventEmitter<string>();
sendMessage() {
this.messageEvent.emit(this.message);
}
}
在 child 组件中,通过在属性声明前添加 @Output() 装饰器,将该属性声明为一个可从子级组件触发的输出事件。然后可以在子组件的方法中使用 emit() 方法触发该事件,并将数据作为参数传递给父组件。
// parent.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<app-child (messageEvent)="receiveMessage($event)"></app-child>
<h2>{{receivedMessage}}</h2>
`,
})
export class ParentComponent {
receivedMessage: string;
receiveMessage($event) {
this.receivedMessage = $event;
}
}
在 parent 组件中,通过在子组件的标签中添加 (messageEvent) 事件绑定,将该输出事件订阅到一个方法上。该方法会接收由子组件发出的事件,并将数据作为参数传递给该方法。
在一些情况下,组件间需要的数据可能过多或过于复杂,此时建议使用服务来进行数据共享。Angular 的服务会创建一个单例对象,可以在组件间共享数据。
// data.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class DataService {
message = 'message from service';
constructor() {}
updateMessage(newMessage: string) {
this.message = newMessage;
}
}
在一个名为 DataService 的服务中定义了一个 message 属性和一个 updateMessage() 方法,用于更新 message 属性。
// parent.component.ts
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-parent',
template: `
<button (click)="updateMessage()">Update Message</button>
<app-child></app-child>
`,
})
export class ParentComponent {
constructor(private dataService: DataService) {}
updateMessage() {
this.dataService.updateMessage('new message from parent');
}
}
在 parent 组件中,可以通过创建一个 DataService 的实例,并将其注入到构造函数中,来使用 DataService 中定义的方法和属性。
// child.component.ts
import { Component } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-child',
template: '<h2>{{dataService.message}}</h2>',
})
export class ChildComponent {
constructor(public dataService: DataService) {}
}
在 child 组件中,同样可以通过创建一个 DataService 的实例,并将其注入到构造函数中,来使用 DataService 中定义的方法和属性。与 parent 组件共用同一个 DataService 的实例,因此可以在 child 组件中访问到在 parent 组件中更新的 message 属性的值。