Skip to content

传递数据

作者:Yuan Tang
更新于:5 个月前
字数统计:2.3k 字
阅读时长:8 分钟

父传子

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

image-20230607171801424

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

image-20230607171925336

子传父 定义事件

在 Angular 中,子组件可以通过输出属性(@Output())与父组件进行通信。

通过输出属性(@Output())发送事件: 子组件可以定义一个输出属性,并使用 EventEmitter 来发出事件。父组件可以监听这个输出属性,并在事件发生时执行相应的逻辑。 子组件代码示例:

import { Component, EventEmitter, Output } from '@angular/core';
@Component({
 selector: 'app-child',
 template: '<button (click)="sendData()">Send Data</button>'
   })
   export class ChildComponent {
 @Output() dataEvent = new EventEmitter<string>();
  sendData() {
   this.dataEvent.emit('Hello from child component');
 }
   }

父组件模板中使用子组件,并监听子组件的输出属性: html

   <app-child (dataEvent)="handleData($event)"></app-child>

此时$event保存的就是子组件传递过来的数据 然后定义一个handleData方法去接受就行了

在父组件中,定义一个名为 handleData 的方法来处理子组件发出的事件。事件的数据可以通过 $event 参数获取。 通过输入属性和输出属性,子组件可以与父组件进行通信,实现数据的传递和事件的触发。

父传子 定义属性

在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的输入属性,并在模板中使用来显示从父组件传递的数据。 这就是在Angular中将数据从父组件传递给子组件的基本方法。

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

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

双向绑定 [()]

@Input() 属性的名字。比如,如果 @Input() 属性为 size,则 @Output() 属性必须为 sizeChange

后面的 sizerComponent 具有值属性 size 和事件属性 sizeChangesize 属性是 @Input(),因此数据可以流入 sizerComponentsizeChange 事件是一个 @Output(),它允许数据从 sizerComponent 流出到父组件。

子组件使用一个事件触发

html

<button (click)="sendData()">Send Data</button>
  @Input() message: string = '';
  @Output() messageChange = new EventEmitter<string>();
  title = 'Child Component';
  sendData() {
    this.title = this.title.concat('New Title')
    this.messageChange.emit(this.title);
  }

父组件通过自定义的input和output修改接受 注意这个必须满足上述

html

<h1>{{title}}</h1>
<app-child [(message)]="title"></app-child>

ts

  title = 'Angular Doc';
  change(value: string) {
    this.title = value;
  }

ngModel主要用于表单控件和组件之间的双向数据绑定,而 @Input()@Output() 装饰器则主要用于组件之间的双向通信。另外,ngModel是Angular框架提供的内置指令,而 @Input()@Output() 装饰器是Angular中用于自定义组件之间通信的装饰器。

通过服务传递数据

  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属性。

Contributors

Yuan Tang