Angular で @Input、@Output、@ViewChild を使用する基本的な例


提示:以下是本篇文章正文内容,下面案例可供参考

一、@Input

親コンポーネントには、表示するために子コンポーネントに渡すメッセージ プロパティがあります。

ParentComponent (parent.component.ts) のコードは次のとおりです (例)。

import {
    
     Component } from '@angular/core';

@Component({
    
    
  selector: 'app-parent',
  template: `
    <app-child [childMessage]="parentMessage"></app-child>
  `,
})
export class ParentComponent {
    
    
  parentMessage = 'message from parent';
}

ChildComponent (child.component.ts) のコードは次のとおりです (例)。

import {
    
     Component, Input } from '@angular/core';

@Component({
    
    
  selector: 'app-child',
  template: `
    {
    
    {
    
     childMessage }}
  `,
})
export class ChildComponent {
    
    
  @Input() childMessage: string;
}

二、@Output

子コンポーネントにはボタンがあり、このボタンがクリックされたときに親コンポーネントにイベントを送信したいと考えています。

ChildComponent(child.component.ts)は以下のとおりです(例)。

import {
    
     Component, Output, EventEmitter } from '@angular/core';

@Component({
    
    
  selector: 'app-child',
  template: `
    <button (click)="sendMessage()">Send Message</button>
  `,
})
export class ChildComponent {
    
    
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage() {
    
    
    this.messageEvent.emit('Hello from Child Component!');
  }
}

ParentComponent(parent.component.ts)は以下のとおりです(例)。

import {
    
     Component } from '@angular/core';

@Component({
    
    
  selector: 'app-parent',
  template: `
    <app-child (messageEvent)="receiveMessage($event)"></app-child>
  `,
})
export class ParentComponent {
    
    
  childMessage: string;

  receiveMessage($event: string) {
    
    
    this.childMessage = $event;
  }
}

3. @ViewChild

ChildComponent (child.component.ts) のコードは次のとおりです (例)。

import {
    
     Component } from '@angular/core';

@Component({
    
    
  selector: 'app-child',
  template: `
    Welcome to the app!
  `,
})
export class ChildComponent {
    
    
  greet() {
    
    
    alert('Hello from Child Component!');
  }
}

ParentComponent (parent.component.ts) のコードは次のとおりです (例)。

import {
    
     Component, ViewChild, AfterViewInit } from '@angular/core';
import {
    
     ChildComponent } from './child.component';

@Component({
    
    
  selector: 'app-parent',
  template: `
    <app-child></app-child>
    <button (click)="callChildMethod()">Call Child Method</button>
  `,
})
export class ParentComponent implements AfterViewInit {
    
    
  @ViewChild(ChildComponent) childComponent: ChildComponent;

  ngAfterViewInit() {
    
    
    // ViewChild is set after the view has been initialized
    this.childComponent.greet();
  }

  callChildMethod() {
    
    
    this.childComponent.greet();
  }
}

4. @Input、@Output、@ViewChild、RXJS の組み合わせの使用例

@Input、@Output は、特に非同期操作や複雑なイベント ストリームを処理する場合に、RxJS と非常によく組み合わされます。

4.1 @Input と RxJS

@Input プロパティが頻繁に変更される場合は、複雑な計算を実行したり、サーバーから関連データをロードしたりするなど、これらの変更に対応する必要がある場合があります。この場合、RxJS の Subject および switchMap 演算子を使用できます。

private _data = new Subject<Data>();

@Input()
set data(value: Data) {
    
    
  this._data.next(value);
}

ngOnInit() {
    
    
  this._data.pipe(
    switchMap(data => this.loadData(data))
  ).subscribe(result => {
    
    
    // 处理结果
  });
}

loadData 関数は @Input 属性が変更されるたびに呼び出され、前の呼び出しがまだ実行中の場合は自動的にキャンセルされます。

4.2 @Output と RxJS

@Output 属性は通常 EventEmitter のインスタンスですが、EventEmitter 自体は RxJS Subject のサブクラスであるため、すべての RxJS 演算子を使用して @Output イベントを処理できます。

@Output() event = new EventEmitter<Event>();

ngOnInit() {
    
    
  this.event.pipe(
    debounceTime(500)
  ).subscribe(e => {
    
    
    // 处理事件,但如果在500毫秒内有新事件,这个事件将被忽略
  });
}

このように、debounceTime オペレーターを使用して、イベントが頻繁に発生するのを防ぐことができます。

4.3 @ViewChild と RxJS

RxJS 演算子は、@ViewChild クエリの結果に対して使用できます。たとえば、switchMap、mergeMap、concatMap などを使用できる Observable を返すメソッドを含むビュー サブコンポーネントがあるとします。

@ViewChild(ChildComponent) child: ChildComponent;

ngOnInit() {
    
    
  this.child.getData().pipe(
    switchMap(data => this.processData(data))
  ).subscribe(result => {
    
    
    // 处理结果
  });
}

このようにして、子コンポーネントのデータが変更されるたびに processData 関数が呼び出され、前の呼び出しがまだ実行中の場合は自動的にキャンセルされます。

V. まとめ

同じ点:

これらはすべてデコレーターであり、クラスのメンバー変数をマークするために使用されます。どちらもコンポーネント間の対話を実現するために使用されます。

違い:

@Input: 外部コンポーネントまたは親コンポーネントが子コンポーネントにデータを渡すことができます。これは、親コンポーネントの入力を受け取ることができる子コンポーネントのパブリック プロパティに相当します。@Input で装飾された変数は、テンプレート式でバインドできる入力プロパティを表します。

@Output: 子コンポーネントがイベントとデータを親コンポーネントに送信できるようにします。@Output で修飾された変数は通常、イベントの発行に使用される EventEmitter のインスタンスです。子コンポーネントが親コンポーネントにイベントを通知する必要がある場合、この EventEmitter の Emit メソッドを呼び出すことができ、親コンポーネントはこのイベントにバインドできます。

@ViewChild: コンポーネントがその子コンポーネントのインスタンスに内部的にアクセスできるようにします。このデコレータを使用すると、親コンポーネントは子コンポーネントのメソッドを直接呼び出したり、そのデータ メンバーにアクセスしたりできます。@ViewChild は、クラス型またはテンプレート参照変数名を受け取り、対応するクラス インスタンスまたはテンプレート参照変数の値を返します。

@Input 和 @Output 主要用于父子组件之间的数据交互,而 @ViewChild 则更多的是用于在一个组件内部访问其子组件。


Guess you like

Origin blog.csdn.net/weixin_45876175/article/details/132061305