Angular 入門
Angular チュートリアルを開始する
Angularは、Googleによって作成および保守されている広く使用されているWebアプリケーションプラットフォームおよびフレームワークです。これはAngularJSへの完全な書き換えとして機能し、「Angular」という名前は、2以降から始まるフレームワークのすべてのバージョンを含めることを意味します。
TypeScriptはAngularの中核であり、Angularが書かれている言語です。そのため、Angularは TypeScript ライブラリなどの主要なコア機能を実装しながら、追加の HTML を使用してクライアント アプリケーションを構築します。
さまざまな理由から、Angularは開発者の間で人気が高まっています。コンポーネントとクラスベースのシステム、モジュラービルディング、階層構造、シンプルな宣言型テンプレートにより、メンテナンスが容易です。さらに、そのクロスプラットフォーム機能は、サーバーサイドレンダリングの速度など、エンタープライズおよびSMB開発者にとって有利です。
このクイックAngularエッセンシャルガイドでは、Angularの重要な部分と、成長を続けるWebベースのアプリケーションプラットフォームとの連携の背後にある主な概念について説明します。
AngularとAngularJSの違いは何ですか
過去には、Angularや AngularJS を使用したことがあるか、少なくとも聞いたことがあるかもしれません。ただし、Angularと AngularJS の間には、知っておく必要のあるいくつかの主な違いがあります。
- モジュール化 - Angularでは、より多くのコア機能がモジュールに移行しました。
- 階層構造 - Angularは、コンポーネントの階層構造に基づいたアーキテクチャを持っています。
- 構文 - Angularは、イベントバインディングやプロパティバインディングに異なる表現構文を使用します。
- 動的ローディング - Angularは、ライブラリを実行時にメモリにロードし、関数を取得・実行し、その後ライブラリをメモリからアンロードします。
- 反復的コールバック - RxJSを使用することで、Angularは非同期コードやコールバックベースのコードを組み合わせやすくします。
- 非同期テンプレートコンパイル - Angularでは、コントローラーや「スコープ」の概念なしで、テンプレートのレンダリングを一時停止して、テンプレートをコンパイルして定義されたコードを生成することが容易になります。
Angular Ivy
Ivyは、Angularのレンダリングエンジンの書き換え版です。Ivyを使用すると、コンポーネントはお互いに独立してコンパイルできます。これにより、変更があったコンポーネントのみが再コンパイルされるため、開発時間が短縮されます。もしあなたがライブラリやアプリケーションの作者であれば、https://docs.angular.lat/guide/ivyにアクセスし、古い/新しいAngularエンジン間の互換性を達成するための詳細や推奨事項を確認してください。
Tree Shaking(ツリーシェイキング)
Ivyはツリーシェイキングを使用するように設計されており、これによりAngularコンポーネントの管理が改善されます。ツリーシェイキングは、ビルドプロセス中に未使用のコードがバンドルに含まれないようにし、その結果、アプリケーションのサイズが小さくなります。バンドルが小さいということは、起動時間が速くなることを意味します。コード分割により、バンドルはさらに最適化されます。
Locality(ローカリティ)
現在、各コンポーネントは独自のローカル情報で独立してコンパイルできるようになり、Angularアプリ全体をコンパイルするのではなく、変更された部分だけをコンパイルするため、再ビルドが大幅に速くなります。
遅延ロード
Ivyでは、Angular NgModuleを必要とせずにコンポーネントを遅延ロードできるようになりました。また、遅延ロードされたコンポーネントが使用するパッケージは、遅延ロードされたチャンクとしてバンドルされます。
グローバリゼーション
ロケールはコンパイル時に登録する必要はなく、代わりに実行時に動的にロードでき、単一のアプリケーションバンドルで複数の言語をサポートします。つまり、言語を変更したい場合、アプリケーションを再起動する必要はありません。
デバッグ
Ivyはデバッグモードに新しい機能を提供し、スタックトレースの改善を行いました。これにより、エラーがどこから発生したのかについて、より多くの情報が得られるようになります。
テストの高速化
IvyのTestBedの新しい実装では、コンポーネントが手動でオーバーライドされない限り、テスト間での再コンパイルを避けることができます。これにより、テスト速度が40〜50%向上します。
基本的なAngularアーキテクチャ
ここでは、関連するアーキテクチャと、このガイドで説明するビルディングブロックの簡単な概要を示します。
- NgModules - アプリケーション ドメイン、ワークフロー、または関連する機能セット専用のコンポーネント セットのコンパイル コンテキストを宣言します。
- コンポーネント - アプリケーション データとロジックを含むクラスを定義し、ビューを定義する HTML テンプレートと連携します。
- テンプレート - HTML とAngularマークアップを組み合わせて、HTML 要素を表示する前に変更できるようにします。
- ディレクティブ - DOM 内の要素にカスタム動作をアタッチします。
- 双方向データ バインディング - テンプレートのパーツをコンポーネントのパーツと調整します。
- サービス - 通常、狭く明確に定義された目的でモジュール性と再利用性を向上させるために使用されるクラス。
- 依存関係の挿入 - 必要なサービスをコンポーネントに提供し、サービス クラスへのアクセスを提供します。
- ルーティング - アプリケーション内でのナビゲーションの実装を容易にします。
次の図は、ビルディング ブロック間の関係を最もよく表しています。
Angular開発環境のセットアップ
環境を設定するには、まずAngular CLI ツールを使用してAngularをダウンロードする必要があります。Node.js と npm がインストールされていないマシンをお持ちの場合は、こちらからダウンロードしてインストールしてください。次に、Angular CLI のグローバル インストールを実行します。
npm install --g @angular/cli
NgModuleのAngular
「AngularのNgModuleとは何ですか」という質問にたどり着きました。基本的に、AngularのNgModuleは、@NgModuleデコレータによってマークされるクラスです。NgModuleは、関連項目を整理するのに優れており、インジェクターとコンパイラの両方を構成するように機能します。
このデコレータは、コンポーネントのテンプレートをコンパイルする方法と、実行時にインジェクタを作成する方法に関する情報をすべてメタデータオブジェクト内に持っています。ご想像のとおり、@NgModule は、これらの部品に依存する独自の指令、コンポーネント、パイプ、および外部コンポーネント間のギャップを特定し、埋める役割を果たします。
このデコレータは、コンポーネントのテンプレートをコンパイルする方法と、実行時にインジェクタを作成する方法に関する情報をすべてメタデータオブジェクト内に持っていました。ご想像のとおり、@NgModule は、独自の指令、コンポーネント、パイプ、およびこれらの部品に依存する外部コンポーネントとの間のギャップを特定し、埋める役割を果たします。
また、exports プロパティは、モジュールの構成の一部を公開し、外部コンポーネントがそれらを効果的に使用できるようにします。
最後に、@NgModule はアプリケーションの依存関係インジェクターにサービス プロバイダーも追加し、基本的にアプリケーションの適応性を高めます。
Angularディレクティブ - タイプと例
ディレクティブは、DOM 要素を作成し、Angularアプリケーションでその構造または動作を変更します。Angularには3種類のディレクティブがあります。
- コンポーネント - テンプレートを含むディレクティブ。
- 属性ディレクティブ - 要素、コンポーネント、またはその他のディレクティブの外観と動作を変更します。
- 構造ディレクティブ - 要素を追加または削除して DOM レイアウトを変更します。
コンポーネント
Angularアプリケーションでは、ブラウザ (または他の場所) に表示されるのはコンポーネントです。コンポーネントは、次のパーツで構成されています。
- Component クラスと呼ばれる TypeScript クラス
- コンポーネントのテンプレートと呼ばれる HTML ファイル
- コンポーネントのスタイル設定用のオプションの CSS ファイル。
- データとロジックを保持するクラス。
- アプリ内でデータを表示するための HTML テンプレートとスタイル。これはビューとも呼ばれ、ユーザーが画面上に表示して対話します。
- コンポーネントの動作を定義するメタデータ。コンポーネント メタデータは、@Component デコレーターを使用してクラスに適用されます。コンポーネントのさまざまな動作を、@Componentデコレータの入力パラメータであるオブジェクトのプロパティとして渡すことができます。
コンポーネントは、独自のテンプレートを持つディレクティブの一種です。Angularアプリケーションに表示されるものはすべてコンポーネントです。
コンポーネントメタデータ
@Componentデコレーターは、クラスをコンポーネントとして装飾します。これはオブジェクトをパラメーターとして受け取る関数です。@Componentデコレーターでは、コンポーネントの動作を設定するために、さまざまなプロパティの値を設定できます。最もよく使用されるプロパティは以下の通りです
- template - テンプレート
- templateUrl - テンプレートのURL
- Providers - プロバイダー
- styles - スタイル
- styleUrls - スタイルのURL
- selector - セレクター
- encapsulation - カプセル化
- changeDetection - 変更検出
- animations - アニメーション
- viewProviders - ビューのプロバイダー
上記のもの以外にも、いくつかの重要な特性があります。一つずつ見ていきましょう。
Angularの変更検出
「Angular の変更検出とは何か?」という質問に簡単に答えると、変更検出は、Angular がアプリケーションの状態が変更されたかどうか、また DOM を更新する必要があるかを確認するプロセスです。このプロパティは、コンポーネントの変更検出器がどのように動作するかを決定します。コンポーネントのプロパティで ChangeDetectionStrategy を設定します。設定できる値は次の2つです。
- Default
- OnPush
このプロパティについては、以降のセクションで詳しく説明します。
カプセル化
このプロパティはAngularコンポーネントのシャドウ DOM を作成するかどうかを決定します。これにより、コンポーネントの ViewEncapsulation モードが決まります。次の 4 つの値を指定できます。
- Emulated(これがデフォルトです)
- Native
- None
- ShadowDom
コンポーネントの使用
コンポーネントは、Angularアプリケーション内でさまざまな方法で使用できます。
- ルートコンポーネントとして使用する。
- 子コンポーネントとして。別のコンポーネント内でコンポーネントを使用できます。
- ルーティングを使用してコンポーネントに移動します。この場合、コンポーネントはRouterOutletにロードされます。
- ComponentFactoryResolverを使用してコンポーネントを動的にロードします。
コンポーネントはモジュールの一部である必要があります。モジュール内のコンポーネントを使用するには、まずコンポーネントをインポートしてから、モジュールの宣言配列に渡します。
@NgModule({
declarations: [
AppComponent,
ProductComponent
]
})
スタンドアロンコンポーネント
Angular 14のリリースにより、スタンドアロンのコンポーネントをビルドでき、NgModuleで宣言する必要はありません。彼らは独自の依存関係を管理し、別のスタンドアロンコンポーネントを直接インポートできます。
スタンドアロンコンポーネントは、次の方法で作成できます。
ng g c {componentName} --standalone
スタンドアロンテンプレートで他のコンポーネント、ディレクティブ、またはパイプを使用する場合は、「standalone」フラグを設定することで、必要なものをスタンドアロンコンポーネント自体に直接インポートできます。
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-card', standalone: true,imports : [CommonModule], templateUrl: './card.component.html', styleUrls: ['./card.component.css']})
export class CardComponent implements OnInit {
constructor() {} ngOnInit(): void {}}
スタンドアロンコンポーネントは、Angularエコシステムを最大限に活用できます。
Angular、多くの組み込みの構造ディレクティブと属性ディレクティブを提供してくれました。組み込みの構造ディレクティブは *ngFor と *ngIf です。属性ディレクティブは NgStyle と NgModel です。
Angular構造ディレクティブの使用
*ngIf は、実行するステートメントに "if" 条件を提供するために使用される構造体ディレクティブです。式が False 値と評価された場合、要素は DOM から削除されます。True と評価された場合、要素は DOM に追加されます。次のリストについて考えてみます。この場合、 *ngIf ディレクティブは、showMessage プロパティの値が True の場合、DOM に div を追加します。
@Component({
Selector: ‘app-message’, Template: ` < div *ngIf=”showMessage” >Show Message </div> `})
export class AppMessageComponent { showMessage = true; }
*ngIf は DOM 要素を非表示にしたり表示したりしないことに注意してください。むしろ、条件に応じて追加または削除します。*ngFor 構造体ディレクティブは、ループ内に DOM 要素を作成します。以下のリストについて考えてみましょう。この場合、*ngFor ディレクティブは、データ配列内の項目数だけテーブル内の行を追加します。
@Component({
Selector: ‘app-message’, Template: ` <table> <tr *ngFor=’let f of data’> <td>{{f.name}}</td> </tr> </table> `})
export class AppMessageComponent { data = [ {name : 'foo'}, {name: 'koo'} ]; }
ほとんどの場合、カスタム構造ディレクティブを作成する必要はありません。組み込みのディレクティブで十分です。
Angular 画像ディレクティブ
画像ディレクティブは、Angular のバージョン 14.2 で開発者プレビューとしてリリースされ、バージョン 15.0 からは安定版として提供されています。NgOptimizedImage ディレクティブは、画像の読み込みを最適化し、LCP(最大コンテンツの表示時間)を大幅に改善することができます。重要な画像の読み込みを優先し、非優先画像はデフォルトで遅延読み込みされ、<img> タグには自動的に fetchpriority 属性が設定されます。さらに、最適なコーディングプラクティスに従っていることを確認するための警告が組み込まれています。使用可能なプロパティは以下の通りです。タグ。さらに、コードがベスト プラクティスに従っていることを確認するための警告が組み込まれています。使用可能なプロパティは次のとおりです。
- ngSrc - ローダーによって処理され、srcプロパティに適用される画像の名前が含まれています。
- ngSrcset - 幅と密度の記述子のリストを含む
- Width - 画像の幅(ピクセル単位)
- Height - 画像の高さ(ピクセル単位)
- Loading - lazy、eager、または auto のいずれかのタイプを定義します。
- Priority - 画像を高い優先度でロードするかどうかを示します
NgOptimizedImageはスタンドアロンのディレクティブであり、コンポーネントまたは必要なngModuleに直接インポートできます。
import { NgOptimizedImage } from '@angular/common';
// Example with a non-standalone component
@NgModule({
imports: [NgOptimizedImage],})
class AppModule {}
// Example with standalone component
@Component({
standalone: true imports: [NgOptimizedImage],})
class StandaloneComponent {}
Angularにおけるデータバインディングとは
データ バインディングは、コンポーネント クラスとコンポーネント テンプレート間のデータの流れを決定します。これは、データをビュー レイヤーにリンクする手法として使用されます。Angularでのデータ バインディングは簡単で、WPF とは異なり、データ コンテキスト、ビュー モデル、または INotifyPropertyChanged (INPC) について心配する必要はありません。必要なのはHTMLファイルとtypescriptファイルだけです。
Angularには、次の 3 種類のデータ バインディングが用意されています。
- 補完(Interpolation)
- プロパティのバインド(Property binding)
- イベントバインディング(Event binding)
Angularの(Interpolation)とは
Angular補間は一方向のデータ バインディングです。これは、コンポーネントクラスからテンプレートにデータを渡すために使用されます。補間の構文は{{propertyname}}です。
以下に示すようなコンポーネントクラスがあるとしましょう。
export class AppComponent {product = { title: 'Cricket Bat', price: 500 };}
コンポーネントクラスからテンプレートに製品を渡す必要があります。例をシンプルにするために、商品オブジェクトの値をハードコーディングしていることに注意してください。ただし、実際のシナリオでは、API を使用してデータベースからデータをフェッチできます。以下のリストに示すように、補間を使用して製品オブジェクトの値を表示できます。
<h1>Product</h1>
<h2>Title: {{product.title}}</h2>
<h2>Price: {{product.price}}</h2>
補間を使用して、データはコンポーネント クラスからテンプレートに渡されます。理想的には、製品オブジェクトの値が変更されるたびに、テンプレートは製品オブジェクトの更新された値で更新されます。
Angularには、Change Detector サービスと呼ばれるものがあります。これにより、コンポーネント クラスとテンプレートのプロパティの値が相互に同期されます。
したがって、Angularでデータを表示する場合は、補間データ バインディングを使用する必要があります。
プロパティバインディング(Property binding)
Angularには、プロパティ バインディングと呼ばれる別の種類のバインディングが用意されています。プロパティバインディングの構文は、角括弧 [] です。これにより、テンプレート上の HTML 要素のプロパティを、コンポーネントクラスのプロパティで設定できます。
したがって、次のようなコンポーネントクラスがあるとしましょう。
export class AppComponent {
btnHeight = 100; btnWidth = 100;}
これで、プロパティバインディングを使用して、コンポーネントクラスのプロパティを使用して、テンプレート上のボタンの高さと幅のプロパティを設定できるようになりました。
<button [style.height.px] = 'btnHeight' [style.width.px] = 'btnWidth' >Add Product</button>
Angularプロパティバインディングは、HTML要素のプロパティをコンポーネントクラスのプロパティに設定するために使用されます。画像、リスト、テーブルなどの他のHTML要素のプロパティを設定することもできます。コンポーネント クラスのプロパティ値が変更されるたびに、プロパティ バインディングの HTML 要素プロパティが更新されます。
イベント バインディング(Event binding)
Angularは、コンポーネント クラスのテンプレートで発生したイベントをキャプチャするための 3 番目の種類のバインディングを提供します。たとえば、コンポーネント テンプレートには、コンポーネント クラスの関数を呼び出すことができるボタンがあります。これは、イベント バインディングを使用して行うことができます。イベント バインディングの背後にある構文は (eventname) です。
Angular例のこのイベントバインディングでは、次のようなコンポーネントクラスがあるとします。
export class AppComponent {
addProduct() { console.log('add product'); }}
テンプレート上のボタンをクリックしたときに addProduct 関数を呼び出す必要があります。これを行うには、イベント バインディングを使用します。
<h1>Product</h1>
<Button (click)=’addProduct()’>Add Product</button>
Angularでは、次の 3 つのバインドが提供されます。イベント バインディングでは、データはテンプレートからクラスに流れ、プロパティ バインディングと補間では、データはクラスからテンプレートに流れます。
Angularには、組み込みの双方向データ バインディングはありません。ただし、プロパティ バインディングとイベント バインディングを組み合わせると、双方向のデータ バインディングを実現できます。
Angular、双方向のデータバインディングを実現するためのディレクティブngModelを提供し、非常に使いやすいです。まず、FormsModuleをインポートし、次に双方向のデータバインディングを作成できます。
export class AppComponent {
name = 'foo';}
入力ボックスを使用して、nameプロパティを双方向のデータバインドできます。
<input type="text" [(ngModel)]='name' /> <h2>{{name}}</h2>
ご覧のとおり、[(ngModel)]を使用して、入力コントロールと名前プロパティの間に双方向のデータバインディングを作成しています。ユーザーが入力ボックスの値を変更するたびに、name プロパティが更新され、その逆も同様です。
パイプ
パイプは、データを変換するためにテンプレートで使用される関数です。Angular、任意のテンプレートで使用できる組み込みパイプのセットを提供します。
DatePipe は日付を文字列にフォーマットします。
<p>StartDate: {{value | date: 'dd/MM/yyyy'}}</p>
PercentagePipe は値をパーセンテージに変換します。
value = 0.2;
…
<p>Percentage: {{value | percent}}</p> // 20%
文字列の小文字と大文字の変換の大文字と小文字の区別:
<p>Lowercase text: {{value | lowercase}}</p>
<p>Uppercase text: {{value | uppercase}}</p>
カスタムパイプの作成
組み込みされていない特定の変換が必要な場合があり、その場合はカスタム変換を作成できます。PipeTransform クラスを実装するクラスを作成し、ロジックを transform メソッドに配置する必要があります。
import { Pipe, PipeTransform } from ‘@angular/core’;
@Pipe({
name: ‘capitalize’})
export class CapitalizePipe implements PipeTransform {
public transform(text: string): string { return text[0].toUpperCase() + text.slice(1); }}
次に、それを使用するには、モジュール宣言に登録する必要があります。
コンポーネント間の通信
Angularでは、コンポーネントは相互に通信して、オブジェクト、文字列、数値、配列、HTML などのデータを共有します。
コンポーネント通信を理解するには、まずコンポーネント間の関係を理解する必要があります。たとえば、2 つのコンポーネントが互いに関連していない場合、Angularサービスを介して通信します。
別のコンポーネント内でコンポーネントを使用すると、コンポーネント階層が作成されます。別のコンポーネント内で使用されるAngularコンポーネントは子コンポーネントと呼ばれ、外側のコンポーネントは親コンポーネントと呼ばれます。次の図に示すように、AppComponent のコンテキストでは、app-child は子コンポーネントで、AppComponent は親コンポーネントです。
import { Component } from '@angular/core';
@Component({
selector: 'app-root', template: ` <h1>Hello {{message}}</h1> <app-child></app-child> //child component `}) export class AppComponent { //parent componentmessage = 'I am Parent';}
親コンポーネントと子コンポーネントは、次の方法で相互に通信できます。
- @Input()
- @Output()
- テンプレート参照変数(Temp Ref Variable)
- ViewChild
- ContentChild
コンポーネントが相互に関連していない場合、コンポーネントはサービスを使用して通信します。それ以外の場合は、通信基準に応じてさまざまなオプションのいずれかを使用して通信します。すべてのオプションを1つずつ調べてみましょう。
@INPUT
@Inputデコレータを使用して、親コンポーネントから子コンポーネントにデータを渡すことができます。データは、プリミティブ型の文字列、数値、オブジェクト、配列など、任意の形式にすることができます。
@Inputの使用方法を理解するために、コンポーネントを作成しましょう。
import { Component } from '@angular/core';
@Component({
selector: 'app-child', template: `<h2> Hi {{greetMessage}}</h2>`})
export class AppChildComponent {
greetMessage = ‘I am Child’;}
AppComponent は AppChildComponent を使用しているため、AppComponent が親コンポーネントで、AppChildComponent が子コンポーネントです。データを渡すために、@Inputデコレータは子コンポーネントのプロパティを使用します。これを行うには、次のリストに示すように、子AppChildComponentを変更する必要があります。
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-child', template: `<h2> Hi {{greetMessage}}</h2>`})
export class AppChildComponent implements OnInit {
@Input() greetMessage: string; constructor() { } ngOnInit() { }}
お気づきのように、greetMessageプロパティを@Input()デコレータで変更しました。したがって、基本的に、子コンポーネントでは、greetMessageプロパティを@Input()デコレータで装飾し、greetMessageプロパティの値を親コンポーネントから設定できるようにしました。次に、親コンポーネントの AppComponent を変更して、子コンポーネントにデータを渡しましょう。
import { Component } from '@angular/core';
@Component({
selector: 'app-root', template: ` <h2>Hello {{message}}</h2>`})
export class AppComponent {
message = 'I am Parent'; childmessage = 'I am passed from Parent to child component';}
親コンポーネントから、子コンポーネントのプロパティgreetMessageの値を設定しています。子コンポーネントに値を渡すには、子コンポーネントのプロパティを角括弧で囲み、その値を親コンポーネントの任意のプロパティに設定する必要があります。親コンポーネントから子コンポーネントのgreetMessageプロパティにchildmessageプロパティの値を渡しています。
@OUTPUT
@Outputデコレータを使用して、子コンポーネントから親コンポーネントにイベントを発行できます。
テンプレート参照変数(Temp Ref Variable)
イベントバインディングを使用して、Angularで双方向バインディングを実現する方法をご覧ください。@Outputを使用して、別のコンポーネントにイベントを発行します。AppChildComponent を以下のリストのように変更してみましょう。
import { Component, Input, EventEmitter, Output } from '@ angular/core';
@Component({
selector: 'app-child', template: `<button (click)=”handleClick()”>Click me</button> `})
export class AppChildComponent {
handleClick() { console.log(‘hey I am clicked in child’); }}
AppChildComponent テンプレートには、関数 handleClick を呼び出すボタンがあります。以下のリストに示すように、AppComponent 内で app-child コンポーネントを使用してみましょう。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root', template: ``})
export class AppComponent implements OnInit {ngOnInit() { }}
ここでは、AppComponent 内で AppChildComponent を使用しています。これにより、AppComponent が親で AppChildComponent が子である親/子のような関係が作成されます。アプリケーションを実行すると、ブラウザコンソールに次のメッセージが表示されます。
これまでは、イベント バインディングを使用して、コンポーネント内の関数を呼び出すボタンを取得するのは非常に簡単です。次に、要件を少し調整してみましょう。AppChildComponent内のボタンのクリックイベントでAppComponentの関数を実行する場合はどうなりますか?
これを行うには、AppChildComponent からボタンクリックイベントを発行する必要があります。EventEmitter をインポートし、@angular/core から出力します。
ここでは、イベントを発行し、イベントにパラメーターを渡します。次のコード リストに示すように、AppChildComponent を変更します。
import { Component, EventEmitter, Output } from '@angular core';
@Component({
selector: 'app-child', template: `<button (click)=”valueChanged()”>Click me</button>`})
export class AppChildComponent {
@Output() valueChange = new EventEmitter(); counter = 0; valueChanged() { this.counter = this.counter + 1; this.valueChange.emit(this.counter); }}
AppChildComponent クラスで次のタスクを実行しました。
- 出力されたイベントのパラメータとして渡される counter という変数を作成しました。
- 親コンポーネントに出力される EventEmitter valueChange を作成しました。
- valueChanged() という名前の関数を作成しました。この関数は、ボタンのクリック イベントで呼び出され、関数内でイベント valueChange が発行されます。
- valueChange イベントを発行する間、カウンターの値はパラメーターとして渡されます。親コンポーネント AppComponent では、次のリストに示すように、子コンポーネント AppChildComponent を使用できます。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root', template: ` <app-child (valueChange)='displayCounter($event)'> `})
export class AppComponent implements OnInit {
ngOnInit() { } displayCounter(count) { console.log(count); }}
現在、AppComponent クラスで次のタスクを実行しています。
- テンプレートで <app-child> を使用します。
- <app-child> 要素で、イベント バインディングを使用して valueChange イベントを使用します。
- valueChange イベントで displayCounter 関数を呼び出します。
- displayCounter 関数で、AppChildComponent から渡されたカウンタの値を出力します。
ご覧のとおり、AppComponentの関数は、AppChildComponentに配置されたボタンのクリックイベントで呼び出されます。これは、@Output と EventEmitter を使用して実行できます。アプリケーションを実行してボタンをクリックすると、ブラウザコンソールにカウンタの値が表示されます。ボタンをクリックするたびに、カウンター値が 1 ずつ増加します。
読み続けて
続きを読むにはフォームに記入してください。