angular组件通信

118 阅读1分钟

父传子

例如父组件ts文件有个title属性子组件是peek-aboo

image-20230607171801424

通过在子组件中@input()装饰器定义一个变量保存改属性

image-20230607171925336

子传父

在Angular中,父组件可以使用@Input装饰器从其子组件中接收数据。具体步骤如下: 1. 在子组件中,定义一个带有@Output装饰器的属性,用于向父组件传递数据。例如,您可以定义一个名为outputData的属性:

import { Component, EventEmitter, Output } from '@angular/core';
​
@Component({
  selector: 'app-child',
  template: `
    <button (click)="sendData()">Send Data</button>
  `
})
export class ChildComponent {
  @Output() outputData = new EventEmitter<string>();
​
  sendData() {
    const data = 'Data from child component';
    this.outputData.emit(data);
  }
}
  1. 在父组件中,使用子组件的选择器,并在其上添加一个带有@Input装饰器的属性,用于接收子组件发送的数据。例如,您可以定义一个名为receivedData的属性:
import { Component } from '@angular/core';
​
@Component({
  selector: 'app-parent',
  template: `
    <app-child (outputData)="receivedData($event)"></app-child>
    <p>Received data: {{ receivedData }}</p>
  `
})
export class ParentComponent {
  receivedData: string;
​
  receivedData(data: string) {
    this.receivedData = data;
  }
}

在这个例子中,父组件使用了子组件的选择器,并在其上添加了一个名为outputData的事件绑定,用于接收子组件发送的数据。当子组件调用sendData()方法时,它会触发outputData事件,并将数据发送给父组件。父组件中的receivedData()方法会接收这个数据,并将其保存在一个名为receivedData的属性中。父组件的模板中,您可以使用{{ receivedData }}来显示接收到的数据。 这就是在Angular中将子组件内容传递给父组件的基本方法。

父传子

在Angular中,父组件可以使用@Input装饰器将数据传递给其子组件。具体步骤如下: 1. 在父组件中,定义一个属性,并使用@Input装饰器将其标记为可传递给子组件的属性。例如,您可以定义一个名为parentData的属性:

import { Component } from '@angular/core';
@Component({
  selector: 'app-parent',
  template: `
    <app-child [childData]="parentData"></app-child>
  `
})
export class ParentComponent {
  parentData = 'Data from parent component';
}

在这个例子中,父组件定义了一个名为parentData的属性,并在其上使用了@Input装饰器。在父组件的模板中,使用子组件的选择器,并将parentData绑定到子组件的childData属性上。 2. 在子组件中,使用@Input装饰器声明一个名为childData的输入属性。例如,您可以定义一个名为ChildComponent的子组件,并在其中声明一个名为childData的输入属性:

import { Component, Input } from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
    <p>Received data: {{ childData }}</p>
  `
})
export class ChildComponent {
  @Input() childData: string;
}

在这个例子中,子组件使用@Input装饰器声明了一个名为childData的输入属性,并在模板中使用{{ childData }}来显示从父组件传递的数据。 这就是在Angular中将数据从父组件传递给子组件的基本方法。

除了使用@Input和@Output装饰器之外,Angular中还有其他几种方法可以在组件之间传递数据。以下是其中的一些方法:

  1. 服务:您可以使用Angular的服务来共享数据。您可以在服务中定义一个变量来保存数据,并在需要使用该数据的组件中注入该服务。这样,您就可以在组件之间共享数据了。
  2. rxjs:rxjs是一个强大的JavaScript库,用于处理异步数据流。您可以使用rxjs的Observable对象来传递数据。您可以在一个组件中创建一个Observable对象,并在需要使用该数据的组件中订阅该Observable对象。这样,当数据发生变化时,订阅它的组件将自动接收到更新后的数据。
  3. ngxs:ngxs是一个Angular状态管理库,它可以帮助您管理应用程序的状态。您可以在ngxs store中定义一个变量来保存数据,并在需要使用该数据的组件中注入该store。这样,您就可以在组件之间共享数据了。
  4. 观察者模式:观察者模式是一种设计模式,它允许对象之间建立一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都将自动得到通知。您可以在一个组件中定义一个观察者对象,并在需要使用该数据的组件中注册该观察者对象。当数据发生变化时,观察者对象将自动通知所有注册它的组件。

通过服务传递数据

  1. 创建一个服务,例如DataService:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
​
@Injectable({
  providedIn: 'root'
})
export class DataService {
  private dataSubject = new BehaviorSubject<string>('');
​
  setData(data: string) {
    this.dataSubject.next(data);
  }
​
  getData() {
    return this.dataSubject.asObservable();
  }
}

在这个服务中,我们使用了rxjs的BehaviorSubject对象来保存数据。setData方法用于更新数据,getData方法用于获取数据。注意,我们使用了@Injectable装饰器来标记这个服务,以便在需要时自动注入它。 2. 在发送数据的组件中,注入DataService服务,并使用setData方法来更新数据:

import { Component } from '@angular/core';
import { DataService } from './data.service';
​
@Component({
  selector: 'app-sender',
  template: `
    <input [(ngModel)]="data" (keyup.enter)="sendData()">
    <button (click)="sendData()">Send</button>
  `
})
export class SenderComponent {
  data: string;
​
  constructor(private dataService: DataService) {}
​
  sendData() {
    this.dataService.setData(this.data);
    this.data = '';
  }
}

在这个组件中,我们定义了一个名为data的属性,并在模板中使用双向绑定和事件绑定来更新它。当用户按下回车键或点击发送按钮时,我们调用setData方法来更新数据。 3. 在接收数据的组件中,注入DataService服务,并使用getData方法来获取数据:

import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
​
@Component({
  selector: 'app-receiver',
  template: `
    <p>{{ data }}</p>
  `
})
export class ReceiverComponent implements OnInit {
  data: string;
​
  constructor(private dataService: DataService) {}
​
  ngOnInit() {
    this.dataService.getData().subscribe(data => this.data = data);
  }
}

在这个组件中,我们定义了一个名为data的属性,并在模板中使用插值表达式来显示它。在ngOnInit方法中,我们使用getData方法来订阅数据的变化,并在回调函数中更新data属性。

使用rxjs通信

  1. 使用rxjs: 在发送数据的组件中,定义一个Observable对象,并在点击按钮时发送数据:
import { Component } from '@angular/core';
import { Observable, Subject } from 'rxjs';
 @Component({
  selector: 'app-sender',
  template: `
    <input [(ngModel)]="data" (keyup.enter)="sendData()">
    <button (click)="sendData()">Send</button>
  `
})
export class SenderComponent {
  data: string;
  data$: Observable<string>;
  private dataSubject = new Subject<string>();
   constructor() {
    this.data$ = this.dataSubject.asObservable();
  }
   sendData() {
    this.dataSubject.next(this.data);
    this.data = '';
  }
}

在接收数据的组件中,订阅这个Observable对象,并在回调函数中更新数据:

import { Component } from '@angular/core';
import { SenderComponent } from './sender.component';
 @Component({
  selector: 'app-receiver',
  template: `
    <p>{{ data }}</p>
  `
})
export class ReceiverComponent {
  data: string;
   constructor(private sender: SenderComponent) {}
   ngOnInit() {
    this.sender.data$.subscribe(data => this.data = data);
  }
}

在这个示例中,我们在发送数据的组件中定义了一个名为dataSubject的Subject对象,并将它转换为一个Observable对象。在发送数据时,我们调用dataSubject的next方法来发送数据。在接收数据的组件中,我们注入了发送数据的组件SenderComponent,并在ngOnInit方法中订阅data$对象。当数据发生变化时,我们在回调函数中更新data属性。

使用ngxs通信

  1. 使用ngxs: 在ngxs store中定义一个变量来保存数据:
import { Injectable } from '@angular/core';
import { State, Action, StateContext } from '@ngxs/store';
 @State<string>({
  name: 'data',
  defaults: ''
})
@Injectable()
export class DataState {
  @Action(SetData)
  setData(ctx: StateContext<string>, { payload }: SetData) {
    ctx.setState(payload);
  }
}
export class SetData {
  static readonly type = '[Data] Set';
  constructor(public payload: string) {}
}

在发送数据的组件中,使用ngxs store的dispatch方法来发送数据:

import { Component } from '@angular/core';
import { Store } from '@ngxs/store';
import { SetData } from './data.state';
 @Component({
  selector: 'app-sender',
  template: `
    <input [(ngModel)]="data" (keyup.enter)="sendData()">
    <button (click)="sendData()">Send</button>
  `
})
export class SenderComponent {
  data: string;
   constructor(private store: Store) {}
   sendData() {
    this.store.dispatch(new SetData(this.data));
    this.data = '';
  }
}

在接收数据的组件中,使用ngxs store的select方法来获取数据:

import { Component } from '@angular/core';
import { Select, Store } from '@ngxs/store';
 @Component({
  selector: 'app-receiver',
  template: `
    <p>{{ data$ | async }}</p>
  `
})
export class ReceiverComponent {
  @Select(state => state.data) data$: Observable<string>;
   constructor(private store: Store) {}
}

在这个示例中,我们在ngxs store中定义了一个名为data的变量,并在发送数据的组件中使用了SetData action来更新它。在接收数据的组件中,我们使用了ngxs store的select方法来获取data变量,并将它转换为一个Observable对象。在模板中,我们使用了async管道来订阅data$对象,并自动更新data属性。