Angular でコンポーネント間で通信する方法について話しましょう

青灯夜游
リリース: 2022-05-17 21:02:28
転載
2475 人が閲覧しました

この記事は、angular の学習を継続し、Angular でのコンポーネント通信の方法を理解するのに役立ちます。

Angular でコンポーネント間で通信する方法について話しましょう

前回の記事では、 Angular と NG-ZORRO の迅速な開発の組み合わせについて話しました。フロントエンド開発は主にコンポーネントベースの開発であり、コンポーネント間の通信と常に切り離すことができません。では、Angular 開発では、コンポーネント間の通信はどのようなものになるのでしょうか? [関連チュートリアルの推奨事項: "angular チュートリアル"]

1 つの例から推測すると、

VueReact はマイナーな点で似ています。違い

この記事は純粋なテキストであり、比較的退屈です。コンソールに表示される内容はあまり役に立たないので、画像は省略します。うーん、読者の皆さんは説明コードに従って理解していただければ幸いです~

1. 親コンポーネントは、属性を介して子コンポーネントに値を渡す

これは、プロパティをカスタマイズし、コンポーネントの導入を通じてサブコンポーネントに値を渡すことと同じです。

コードを見せてください

<!-- parent.component.html -->

<app-child [parentProp]="&#39;My kid.&#39;"></app-child>
ログイン後にコピー

親コンポーネント内で子コンポーネントを呼び出します。ここでは

parentProp 属性に名前を付けます。

// child.component.ts

import { Component, OnInit, Input } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-child&#39;,
  templateUrl: &#39;./child.component.html&#39;,
  styleUrls: [&#39;./child.component.scss&#39;]
})
export class ChildComponent implements OnInit {
  // 输入装饰器
  @Input()
  parentProp!: string;

  constructor() { }

  ngOnInit(): void {
  }
}
ログイン後にコピー

子コンポーネントは、親コンポーネントから渡された変数

parentProp を受け入れ、それをページにバックフィルします。

<!-- child.component.html -->

<h1>Hello! {{ parentProp }}</h1>
ログイン後にコピー

2. 子コンポーネントは、エミッター イベントを通じて親コンポーネントに情報を渡します。

子コンポーネントのデータを、

new EventEmitter を通じて親に渡します。 () コンポーネント。

// child.component.ts

import { Component, OnInit, Output, EventEmitter } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-child&#39;,
  templateUrl: &#39;./child.component.html&#39;,
  styleUrls: [&#39;./child.component.scss&#39;]
})
export class ChildComponent implements OnInit {
  // 输出装饰器
  @Output()
  private childSayHi = new EventEmitter()

  constructor() { }

  ngOnInit(): void {
    this.childSayHi.emit(&#39;My parents&#39;);
  }
}
ログイン後にコピー

emit を通じて親コンポーネントに通知し、親コンポーネントはイベントを監視します。

// parent.component.ts

import { Component, OnInit } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-communicate&#39;,
  templateUrl: &#39;./communicate.component.html&#39;,
  styleUrls: [&#39;./communicate.component.scss&#39;]
})
export class CommunicateComponent implements OnInit {

  public msg:string = &#39;&#39;

  constructor() { }

  ngOnInit(): void {
  }

  fromChild(data: string) {
    // 这里使用异步
    setTimeout(() => {
      this.msg = data
    }, 50)
  }
}
ログイン後にコピー

親コンポーネントでは、

コンポーネントからのデータを監視した後、setTimeoutの非同期操作を使用します。これは、サブコンポーネントでの初期化後に emit を実行したためです。ここでの非同期操作は、Race Condition 競合エラーを防ぐためです。

また、次のように

fromChild メソッドをコンポーネントに追加する必要があります:

<!-- parent.component.html -->

<h1>Hello! {{ msg }}</h1>
<app-child (childSayHi)="fromChild($event)"></app-child>
ログイン後にコピー

3. 参照を通じて、親コンポーネントはプロパティとメソッドを取得します。子コンポーネントの

参照を操作してサブコンポーネント オブジェクトを取得し、そのプロパティとメソッドにアクセスします。

最初に子コンポーネントのデモ コンテンツを設定します:

// child.component.ts

import { Component, OnInit } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-child&#39;,
  templateUrl: &#39;./child.component.html&#39;,
  styleUrls: [&#39;./child.component.scss&#39;]
})
export class ChildComponent implements OnInit {

  // 子组件的属性
  public childMsg:string = &#39;Prop: message from child&#39;

  constructor() { }

  ngOnInit(): void {
    
  }

  // 子组件方法
  public childSayHi(): void {
    console.log(&#39;Method: I am your child.&#39;)
  }
}
ログイン後にコピー

親コンポーネントに子コンポーネントの参照識別子を設定します

#childComponent:

<!-- parent.component.html -->

<app-child #childComponent></app-child>
ログイン後にコピー

javascript

ファイルの呼び出し後: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">import { Component, OnInit, ViewChild } from &amp;#39;@angular/core&amp;#39;; import { ChildComponent } from &amp;#39;./components/child/child.component&amp;#39;; @Component({ selector: &amp;#39;app-communicate&amp;#39;, templateUrl: &amp;#39;./communicate.component.html&amp;#39;, styleUrls: [&amp;#39;./communicate.component.scss&amp;#39;] }) export class CommunicateComponent implements OnInit { @ViewChild(&amp;#39;childComponent&amp;#39;) childComponent!: ChildComponent; constructor() { } ngOnInit(): void { this.getChildPropAndMethod() } getChildPropAndMethod(): void { setTimeout(() =&gt; { console.log(this.childComponent.childMsg); // Prop: message from child this.childComponent.childSayHi(); // Method: I am your child. }, 50) } }</pre><div class="contentsignin">ログイン後にコピー</div></div>このメソッドには制限がありますか? つまり、サブプロパティの修飾子は

public## である必要があります。 #、

protected または private の場合、エラーが報告されます。サブコンポーネントの修飾子を変更してみてください。エラーの理由は次のとおりです:

タイプ使用範囲public 最も広いスコープ内外での呼び出しを許可 protected クラスおよび継承されたサブクラス内での使用を許可、スコープは中程度です クラス内での使用が許可されますが、スコープは最も狭いです##4. サービスを通じて
#private
を変更するには、

rxjs を使用してデモンストレーションします。

rxjs は、Observables

を使用したリアクティブ プログラミング用のライブラリです。これにより、非同期またはコールバック ベースのコードを簡単に作成できます。

rxjs を記録する記事が後ほどありますので、お楽しみに

まず、parent-and- という名前のファイルを作成しましょう。子 サービス。

// parent-and-child.service.ts

import { Injectable } from &#39;@angular/core&#39;;
import { BehaviorSubject, Observable } from &#39;rxjs&#39;; // BehaviorSubject 有实时的作用,获取最新值

@Injectable({
  providedIn: &#39;root&#39;
})
export class ParentAndChildService {

  private subject$: BehaviorSubject<any> = new BehaviorSubject(null)

  constructor() { }
  
  // 将其变成可观察
  getMessage(): Observable<any> {
    return this.subject$.asObservable()
  }

  setMessage(msg: string) {
    this.subject$.next(msg);
  }
}
ログイン後にコピー
次に、親コンポーネントと子コンポーネントで参照し、情報を共有します。

// parent.component.ts

import { Component, OnDestroy, OnInit } from &#39;@angular/core&#39;;
// 引入服务
import { ParentAndChildService } from &#39;src/app/services/parent-and-child.service&#39;;
import { Subject } from &#39;rxjs&#39;
import { takeUntil } from &#39;rxjs/operators&#39;

@Component({
  selector: &#39;app-communicate&#39;,
  templateUrl: &#39;./communicate.component.html&#39;,
  styleUrls: [&#39;./communicate.component.scss&#39;]
})
export class CommunicateComponent implements OnInit, OnDestroy {
  unsubscribe$: Subject<boolean> = new Subject();

  constructor(
    private readonly parentAndChildService: ParentAndChildService
  ) { }

  ngOnInit(): void {
    this.parentAndChildService.getMessage()
      .pipe(
        takeUntil(this.unsubscribe$)
      )
      .subscribe({
        next: (msg: any) => {
          console.log(&#39;Parent: &#39; + msg); 
          // 刚进来打印 Parent: null
          // 一秒后打印 Parent: Jimmy
        }
      });
    setTimeout(() => {
      this.parentAndChildService.setMessage(&#39;Jimmy&#39;);
    }, 1000)
  }

  ngOnDestroy() {
    // 取消订阅
    this.unsubscribe$.next(true);
    this.unsubscribe$.complete();
  }
}
ログイン後にコピー
import { Component, OnInit } from &#39;@angular/core&#39;;
import { ParentAndChildService } from &#39;src/app/services/parent-and-child.service&#39;;

@Component({
  selector: &#39;app-child&#39;,
  templateUrl: &#39;./child.component.html&#39;,
  styleUrls: [&#39;./child.component.scss&#39;]
})
export class ChildComponent implements OnInit {
  constructor(
    private parentAndChildService: ParentAndChildService
  ) { }
  
  
  // 为了更好理解,这里我移除了父组件的 Subject
  ngOnInit(): void {
    this.parentAndChildService.getMessage()
      .subscribe({
        next: (msg: any) => {
          console.log(&#39;Child: &#39;+msg);
          // 刚进来打印 Child: null
          // 一秒后打印 Child: Jimmy
        }
      })
  }
}
ログイン後にコピー
親コンポーネントでは、1 秒後に値を変更します。したがって、親子コンポーネントでは、msg

の初期値

null

が入力されるとすぐに出力され、1 秒後に変更された値

Jimmy# が出力されます。 ## が出力されます。同様に、子コンポーネントにサービス情報を指定すると、子コンポーネントが関連する値を出力するときに、親コンポーネントにも出力されます。 【終了】プログラミング関連の知識については、プログラミング入門をご覧ください。 !

以上がAngular でコンポーネント間で通信する方法について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート