Angularの動的コンポーネントの詳細な説明

Angularの動的コンポーネントの詳細な説明

使用シナリオ

まず、動的コンポーネントの使用シナリオを明確にしましょう。簡単に言えば、コードの実行中にコンポーネントを動的にロードするには、特定の状況 (ユーザー操作、バックエンドからの結果の要求など) に基づいて、特定のコンポーネントをロードする場所をコードで決定する必要があります。これらのコンポーネントは静的 (固定) ではありません。

公式サイトで示されている例では、動的な広告バナーを構築する場合、新しい広告コンポーネントが継続的にリリースされるため、静的なコンポーネント構造のみをサポートするテンプレートを使用することは明らかに非現実的です。

もう 1 つの一般的な例として、動的ポップアップ ボックスを見てみましょう。ポップアップするコンポーネントは不確定で、常に更新されます。あちこちに購入ボックスがポップアップし、あちこちにスタイル選択ボックスがポップアップします。静的なコンポーネント構造テンプレートでは、大衆の増大するニーズを満たすことができません。

達成方法

次に、動的コンポーネントを実装するために必要なものを把握します。

1. 動的コンポーネントを配置する場所

動的コンポーネントを追加する場所、つまりアンカー ポイントを知る必要があります。では、コンポーネントをロードするには何を使用できるでしょうか?

コンポーネントはアンカーにロードされるのではないのか、アンカーは DOM ノードではないのか、と思われるかもしれません。もちろん、DOM ノードにロードされます。

まず、Angular の DOM を操作する一般的な方法を確認しましょう。DOM を操作するネイティブ JS メソッドについては考えないでください。Angular コンポーネントをロードできるオブジェクトを返すことができると思いますか?

Angular は、DOM クエリと呼ばれるテクノロジを提供します。これは主に、同じ基本機能を持つ @ViewChild および @ViewChildren デコレータから提供されます。

@ViewChild: セレクターに一致するビューの DOM 内の最初の要素またはディレクティブへの単一の参照を返します。

@ViewChildren : QueryList オブジェクトでラップされた複数の参照を返し、セレクターに一致するすべての要素またはディレクティブをビューの DOM で検索します。

基本的な構文:

@ViewChild([テンプレートからの参照], {読み取り: [参照タイプ]});

DOM クエリ テクノロジーによって検出されたオブジェクトは、次の 3 つのカテゴリに分類されます。

ElementRef: span のような単純な HTML 要素にマウントされている場合。

TemplateRef: テンプレート要素にマウントされている場合。

ViewContainerRef: 推測できません。通常、プログラマーは読み取り時にこれを指定する必要があります。任意の DOM 要素をビュー コンテナーとして使用できます。

公式ウェブサイトの API から、ViewContainerRef だけがコンポーネントに 1 つ以上のビューをアタッチできるコンテナーであり、つまりコンポーネントをロードできるコンテナーであることがわかります。ただし、新しいコンポーネントを兄弟 (ノード) として扱うことができるのは DOM 要素 (コンテナー) であることに注意してください。親子関係ではなく、兄弟です。

コンテナをロードするために ViewContainerRef が使用されていることがわかりました。ViewContainerRef を取得するには 2 つの方法があります。

1つ目は、上記のDOMクエリを通じて@ViewChildをクエリすることです。

<ng-container #addComp></ng-container>
@ViewChild('addComp', {読み取り: ViewContainerRef}) adComp:ViewContainerRef;

2つ目は、依存性注入を使用した公式ウェブサイトの例です。

'@angular/core' から Directive、ViewContainerRef をインポートします。

@指令({
セレクタ: '[ad-host]',
})
エクスポートクラスAdDirective {
コンストラクター(パブリック viewContainerRef: ViewContainerRef) { }
}

アンカーポイントはng-templateに設定され、ViewContainerRefはディレクティブインジェクションを通じて取得されます。

テンプレート: `
<div class="広告バナーの例">
<h3>広告</h3>
<ng-template 広告ホスト></ng-template>
</div>

2. コンポーネントのインスタンスを取得する方法

コンポーネントをビューにロードすることは、新しいメソッドでインスタンス化してから、append、insert などでアタッチするほど簡単ではありません。動的コンポーネントは、事前にコンパイラによってコンパイルおよび保存され、その後 ComponentFactory でカプセル化される必要があります。後続の Component インスタンスは、ComponentFactory を通じて作成する必要があります。この記事 [翻訳] Angular の動的コンポーネントについて知っておくべきこと を読むことができますが、SystemJsNgModuleLoader モジュール ローダーは非推奨になったと記載されています。

ComponentFactoryResolver は、ComponentFactory がコンポーネント インスタンスを作成するために使用できる生成されたクラスにコンポーネントをマップする単純なレジストリです。これを使用すると、特定のコンポーネント タイプのファクトリを取得し、ファクトリの create() メソッドを使用してそのタイプのコンポーネントを作成できます。

公式サイトのサンプルコードを見てみましょう。以下は完全なコードではありません。

//ComponentFactoryResolver を注入する
コンストラクター(プライベートcomponentFactoryResolver: ComponentFactoryResolver) { }
 
ロードコンポーネント() {
......
// 広告コンポーネントインスタンスの作成に使用できる生成された ComponentFactory を取得します
const コンポーネントファクトリ = this.componentFactoryResolver.resolveComponentFactory(adItem.component);
 
// コンポーネントをロードするためのコンテナを取得します。const viewContainerRef = this.adHost.viewContainerRef;
ビューコンテナリファレンスをクリアします。
 
// コンポーネントをコンテナに配置し、いくつかのパラメータを渡します。const componentRef = viewContainerRef.createComponent(componentFactory);
(<AdComponent>componentRef.instance).data = adItem.data;
}

これで終わりだと思いますか? このように書かれたコードは実行できると思いますか?若すぎる場合は、フロント ウェーブで注意すべき点をいくつか示します。

Angular のコンポーネント、ディレクティブ、パイプはすべてモジュールにカプセル化されています。コンポーネントを例にとると、他のモジュールのコンポーネントを使用する場合は、他のモジュールでこのコンポーネントをエクスポートし、独自のモジュールに他のモジュールをインポートする必要があります。したがって、公式 Web サイトの例の手順を忘れずにインポートおよびエクスポートしてください。

動的コンポーネントの場合は、モジュールの entryComponents プロパティにコンポーネントを登録する必要がありますが、エクスポートする必要はありません。モジュールをインポートする必要があります。

以上がAngularの動的コンポーネントの詳細な説明です。Angularの動的コンポーネントの詳細については、123WORDPRESS.COMの他の関連記事をご覧ください。

以下もご興味があるかもしれません:
  • Angularの親子コンポーネント通信の詳細な説明
  • Angular のパフォーマンス最適化: サードパーティ コンポーネントと遅延読み込みテクノロジー
  • Angularコンポーネント間の通信の実装例
  • 角度コンポーネント間の値転送テスト方法の詳細な説明
  • Angular7はプロジェクト、コンポーネント、サービスを作成し、サービスを使用します
  • Angular イベント: 異なるコンポーネント間でデータを渡す方法
  • Angularjs1.5 関数を使用してコンポーネントの外部に値を渡す例
  • Angular6 学習ノートの詳細説明: マスタースレーブコンポーネント
  • Angularコンポーネントの仲介モードの詳細な説明

<<:  Dockerのyumソースの設定とCentOS7へのインストールの詳細な説明

>>:  MySQL 8.0 の新機能の落とし穴と解決策についての簡単な説明 (要約)

推薦する

Vue を使用してパブリック アカウントの Web ページを開発する方法

目次プロジェクトの背景始めるvue-cliでプロジェクトを作成するモバイル適応についてnormali...

LinuxサーバーでRabbitMQ管理ページにアクセスできない問題を解決

私のプロジェクトの特定の機能ではサーバーが rabbitmq にメッセージを送信する必要があるため、...

Linux スワップ パーティション (詳細説明)

目次リナックス1. SWAPとは2. swappiness は何を調節しますか? 3. スワップ操作...

超詳細なMySQL使用仕様の共有

最近、データベース関連の操作が多くなり、会社の既存の仕様はあまり包括的ではありません。インターネット...

Docker イメージ管理の一般的な操作コード例

ミラーリングも Docker のコアコンポーネントの 1 つです。ミラーリングはコンテナ操作の基盤で...

VirtualBox で作成された Debian 仮想マシンは Windows ホストとファイルを共有します

用語: 1. VM: 仮想マシンステップ: 1. Windows 10 に VirtualBox 6...

CSS で適応型ディバイダーを巧みに実装する N 通りの方法

分割線はウェブページでよく使われるデザインです。例えば、Zhihuのその他の回答をご覧ください。 こ...

CentOS7 での mysql 5.7.23 のバイナリ インストール

インターネット上のインストール情報は不均一で、落とし穴だらけです。インストールにはかなりの労力がかか...

jQueryは動的タグイベントを実装します

この記事では、タグイベントを動的に追加するためのjQueryの具体的なコードを参考までに紹介します。...

Xtrabackup を使用した MySQL バックアップ プロセスの詳細な説明

目次01 背景02 はじめに03 ワークフロー04 いくつかの質問05 ファイルをバックアップする0...

DockerでNginxサーバーを作成する方法

動作環境: MAC Docker バージョン: Docker version 17.12.0-ce,...

ウェブページのカラーマッチングスキルについての簡単な説明(フロントエンド開発者必読)

一般的に、Web ページの背景色は、より柔らかく、よりシンプルで、より明るく、暗いテキストとマッチし...

Linux 環境の Apache サーバーでセカンダリドメイン名を設定する方法の詳細な説明

この記事では、Linux 環境の Apache サーバーでセカンダリ ドメイン名を構成する方法につい...

MySQL の日付関数と日付変換およびフォーマット関数

MySQL は、膨大なユーザーベースを持つ無料のリレーショナル データベースです。この記事では、My...

Reactで例外を適切にキャプチャする方法

目次序文エラー境界エラー境界を超えてトライ/キャッチwindow.onerror、エラーイベント未処...