インフラジスティックス・ジャパン株式会社Blog

インフラジスティックス・ジャパン株式会社のチームメンバーが技術トレンド、製品Tips、サポート情報からライセンス、日々の業務から感じることなど、さまざまなトピックについてお伝えするBlogです。

Angularで依存関係のない2つのComponent間でデータを共有する最も簡単な方法

f:id:jack1213:20220325093730j:plain

Angularでは、コンポーネント同士がどのように通信するのかを知っておくことが重要です。あるコンポーネントを別のコンポーネントの中で使用すると、親子関係が生まれます。 このような場合、親コンポーネントと子コンポーネントは以下のような方法で通信を行います。

  • @Input()
  • @Output()
  • Temp Ref Variable
  • ViewChild and ContentChild

この記事はインフラジスティックス本社により作成された英文記事の機械翻訳により生成されました。
原文は以下よりご確認いただけます。
Dhananjay Kumar 2019.4.9  [Simplest way to share data between two unrelated Components in Angular](https://www.infragistics.com/community/blogs/b/infragistics/posts/simplest-way-to-share-data-between-two-unrelated-components-in-angular)
また、本記事の内容に深くご興味がある場合、インフラジスティックス・ジャパンのスタッフによる翻訳リクエストを受け付けておりますので、「JapanPR@infragistics.com」宛にご連絡ください。

今回のブログでは、Angular Serviceを使って、互いに関連性のないコンポーネント間でデータを共有する方法について学びます。

f:id:jack1213:20220325094326p:plain

これを理解するために、サービスを作成します。 そのサービスの中に、countという変数を作ります。 サービスは、count変数の値をコンポーネント間で共有します。count変数を作成する前に、もう一度要件について説明します。すべてのコンポーネントが、サービスを使って共有されたデータの最終更新値にアクセスできるようにしたいと思います。

そのためには、count変数をRxJSのサブジェクトでラップする必要があります。正確にはBehaviorSubjectを使用します。

counter = 1;
count: BehaviorSubject<number>;

constructor() {
    this.count = new BehaviorSubject(this.counter);
}

BehaviorSubjectを使用しているのは、以下の理由からです。

  1. サービスからのデータはマルチキャストであるべきです。各コンシューマーコンポーネントは、データの同じコピーにアクセスする必要があります。この目的のために、BehaviorSubjectが使用されます。
  2. observableはユニキャストのため使用しない。サブスクライバは自分自身のデータコピーを持つことになります。
  3. BehaviorSubjectは現在の値を保存します。したがって、コンポーネントは常にBehaviorSubjectに格納されたデータの現在の値を読み取ることになります。

これらをまとめると、簡単なデータを共有するためのサービスは次のようなコードになります。

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
 
@Injectable({
    providedIn: 'root'
})
export class AppService {
    counter = 1;
    count: BehaviorSubject<number>;
    constructor() {
        this.count = new BehaviorSubject(this.counter);
    }
 
    nextCount() {
        this.count.next(++this.counter);
    }
}

コンポーネントがサービスを使用して、共有データにアクセスできるようになりました。例えば、あるコンポーネントでは、次のリストのようにサービスを使用することができます。

export class Appchild2Component implements OnInit {
 
    count: number;
    constructor(private appsevice: AppService) {
    }
    ngOnInit() {
 
        this.appsevice.count.subscribe(c => {
            this.count = c;
        });
    }
    nextCount() {
        this.appsevice.nextCount();
    }
}

サービスを設定し、ローカル変数のcountの値を読み込んでいます。さらに、countをインクリメントする関数があります。 テンプレート上では、次のコードリストのように、共有データの表示とインクリメントを行うことができます。

<h2>Count in component2  =  {{ count }}</h2>
<button (click)='nextCount()'>Next Count from component2</button>

この方法では、できるだけ多くのコンポーネントでサービスを利用することができ、どこでもサービスから同じデータを共有することができます。参考までに、作業中のコードはこちらでご覧いただけます。

サンプルコード

これがAngularで無関係なコンポーネント間でデータを共有する最も簡単な方法だと思います。もっと複雑なシナリオには、もっと良い方法があると思います。