📜  如何在Angular中将数据从父级传递到子级组件?(1)

📅  最后修改于: 2023-12-03 15:08:51.606000             🧑  作者: Mango

如何在 Angular 中将数据从父级传递到子级组件?

在 Angular 中,组件间的数据传递通常是通过 @Input 和 @Output 装饰器实现的。其中,@Input 装饰器将一个属性声明为可从父组件绑定的输入属性,而 @Output 装饰器则将一个属性声明为一个可以从子组件触发的输出事件。

使用 @Input 装饰器传递数据

假设有如下两个组件: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() 装饰器,将该属性声明为一个可接受从父级组件传递而来的输入属性。

使用 @Output 装饰器传递数据

假设现在需要将一些状态从 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 属性的值。