Angularでカスタムコンポーネントの値受け渡しを理解するためのサンプルコード

2024-06-17

Angular、TypeScript、Angular2-templateにおけるカスタムコンポーネントへの変数受け渡し

入力プロパティは、親コンポーネントから子コンポーネントへのデータ伝達に最も一般的な方法です。

方法

  1. 子コンポーネントの @Input() デコレータでプロパティを定義します。
  2. 親コンポーネントのテンプレートで、子コンポーネントの <ng-component> タグに [property]="value" のようにバインディング属性を設定します。

子コンポーネント (message.component.ts)

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

@Component({
  selector: 'app-message',
  templateUrl: './message.component.html',
})
export class MessageComponent {
  @Input() message: string;
}
<app-message [message]="'Hello, Angular!'"></app-message>

コンテンツ投影は、親コンポーネントのテンプレート内の子コンポーネントの領域を定義し、その領域にコンテンツを挿入する方法です。

  1. 子コンポーネントの <ng-content> タグでコンテンツ挿入箇所を定義します。
<div class="card">
  <ng-content></ng-content>
</div>
<app-card>
  <h3>My Card</h3>
  <p>This is some content.</p>
</app-card>

上記以外にも、@ViewChild デコレータや EventEmitter を用いた方法など、状況に応じてさまざまな方法があります。

補足

  • Angular はバージョンによって API や機能が異なる場合があります。上記の例は Angular 14 をベースにしています。
  • 上記はあくまで基本的な説明であり、より複雑な実装には他のテクニックが必要となる場合があります。



入力プロパティ

例:名前と挨拶を表示するコンポーネント

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

@Component({
  selector: 'app-message',
  templateUrl: './message.component.html',
})
export class MessageComponent {
  @Input() name: string;

  get message(): string {
    return `Hello, ${this.name}!`;
  }
}
<app-message [name]="'Taro'"></app-message>
<app-message [name]="'Hanako'"></app-message>

出力:

Hello, Taro!
Hello, Hanako!

コンテンツ投影

例:見出しと本文を持つカードコンポーネント

<div class="card">
  <h2><ng-content select="h2"></ng-content></h2>
  <p><ng-content></ng-content></p>
</div>
<app-card>
  <h2>My Card</h2>
  <p>This is some content.</p>
</app-card>

<app-card>
  <h2>Another Card</h2>
  <p>This is another content.</p>
</app-card>
<div class="card">
  <h2>My Card</h2>
  <p>This is some content.</p>
</div>

<div class="card">
  <h2>Another Card</h2>
  <p>This is another content.</p>
</div>

上記はあくまで基本的な例であり、実際の開発では状況に応じてさまざまな方法を組み合わせて使用します。

  • コンポーネントのスタイルは CSS ファイルで定義できます。
  • コンポーネントロジックは TypeScript ファイルで記述できます。
  • テストは Jasmine や Karma などのツールを使用して行うことができます。



Angular でカスタムコンポーネントに値を渡すその他の方法

サービスは、コンポーネント間でデータを共有するための方法です。コンポーネントはサービスを注入して、そのサービスのメソッドやプロパティにアクセスできます。

サービス (data.service.ts)

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

@Injectable({
  providedIn: 'root',
})
export class DataService {
  private data: string = 'Hello, Angular!';

  getData(): string {
    return this.data;
  }

  setData(newData: string) {
    this.data = newData;
  }
}
import { Component, Input, OnInit } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-message',
  templateUrl: './message.component.html',
})
export class MessageComponent implements OnInit {
  message: string;

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.message = this.dataService.getData();
  }
}
<app-message></app-message>

RxJS は、非同期データストリームを処理するためのライブラリです。コンポーネントは RxJS オブザーバブルをサブスクライブして、データストリームを購読できます。

import { Component, Input, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';

@Component({
  selector: 'app-message',
  templateUrl: './message.component.html',
})
export class MessageComponent implements OnInit {
  message$: Observable<string>;

  constructor() {
    this.message$ = of('Hello, Angular!');
  }

  ngOnInit(): void {
    this.message$.subscribe((message) => {
      this.message = message;
    });
  }
}
<app-message></app-message>

URL パラメータを使用して、コンポーネント間でデータを渡すこともできます。

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

@Component({
  selector: 'app-message',
  templateUrl: './message.component.html',
})
export class MessageComponent implements OnInit {
  message: string;

  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit(): void {
    this.activatedRoute.queryParams.subscribe((params) => {
      this.message = params['message'];
    });
  }
}
<a routerLink="/message?message=Hello, Angular!">Go to Message</a>

@ViewChild デコレータを使用して、子コンポーネントのインスタンスを親コンポーネントから取得できます。その後、そのインスタンスのプロパティやメソッドにアクセスできます。

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

@Component({
  selector: 'app-message',
  templateUrl: './message.component.html',
})
export class MessageComponent {
  @Input() message: string;

  @Output() messageChanged = new EventEmitter<string>();

  onChange(newMessage: string) {
    this.message = newMessage;
    this.messageChanged.emit(newMessage);
  }
}
<app-message #messageComponent [message]="'Hello, Angular!'"></app-message>

<button (click)="messageComponent.onChange('Hello, World!')">Change Message</button>

@ContentChildren


angular typescript angular2-template


Angular:@angular/routerとActivatedRouteで子ルートから親ルートへナビゲート

Angularアプリケーションでは、ルーティングを使用して、異なるコンポーネント間を遷移します。ルーティングモジュールを使用すると、URLとコンポーネントを関連付け、ブラウザのURLが変更されたときにどのコンポーネントを表示するかを指定できます。...


RxJS の defer オペレータを使用して Promise を Observable に変換する方法

Angular、Firebase、RxJS は、Web アプリケーション開発でよく使われるフレームワークとライブラリです。これらのフレームワーク/ライブラリは、非同期処理を扱うための強力なツールを提供します。Promise と Observable は、非同期処理を扱うための異なる抽象化です。...


Angular 2 無効化されたコントロールが form.value に含まれない問題

問題フォームコントロールが無効化されている場合、そのコントロールの値は form. value オブジェクトに含まれません。これは、無効な値をフォームデータに含めないようにするためです。解決策無効化されたコントロールの値を form. value に含めるには、次のいずれかの方法を使用できます。...


asyncValidatorsプロパティによる条件付き無効化

設定方法disabled属性を設定するには、以下の2つの方法があります。テンプレートでは、formControlNameディレクティブとdisabled属性を組み合わせて使用します。コンポーネントクラスでは、FormControlインスタンスのdisabledプロパティを設定します。...


Angular Mat Select でデフォルトオプションを設定する方法

mat-select にデフォルトオプションを設定するには、value プロパティを使用します。このプロパティには、選択されたオプションの値を設定します。上記のコードでは、selectedValue プロパティに 1 を設定しているため、デフォルトオプションは "オプション 1" になります。...


SQL SQL SQL SQL Amazon で見る



【Angular2】コンポーネント間でデータを受け渡し:InputとOutput編

@Input デコレータは、コンポーネントのプロパティを外部から設定できるようにするものです。以下の例のように、コンポーネントのクラスに @Input デコレータを定義し、プロパティ名を指定します。上記のように定義したコンポーネントをテンプレートで使用する場合、以下の例のように message プロパティに文字列値をバインドします。