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 の新機能の落とし穴と解決策についての簡単な説明 (要約)

推薦する

Nginx gzip設定について

nginx がリソース圧縮を実現する原理は、ngx_http_gzip_module モジュールを介...

Windows システムで MySQL が起動しない場合の一般的な解決策

MySQL 起動エラーWindows 10 に MySQL をインストールする前は、net star...

MySQLクエリのパフォーマンスを分析する方法

目次スロークエリの基礎: データ取得の最適化データベースから不要なデータが要求されていないか確認する...

vue cli3は環境ごとにパッケージ化の手順を実装します

cli3 でビルドされた vue プロジェクトは、ゼロ構成ファイルとして知られています。パッケージ化...

最も完全な 50 の MySQL データベース クエリ演習

このデータベース クエリ ステートメントは、インターネット上の 50 個のデータベース クエリ練習問...

Linux statコマンドの使用

1. コマンドの紹介stat コマンドは、ファイルまたはファイル システムに関する詳細情報を表示する...

JS の精度外数値問題の解決

精度の問題に対する最もわかりやすい説明たとえば、1÷3=0.33333333...という数字は、3が...

nginx 設定チュートリアルにおける add_header の落とし穴の詳細な説明

序文add_header は、headers モジュールで定義されたディレクティブです。名前が示すよ...

JSON.stringify の簡易版の実装とその 6 つの主要機能の詳細な説明

目次序文JSON.stringify の 6 つの機能特集1特集2特集3特集4特集5特集6手動で文字...

MySQLトリガーの使用例の詳細

MySQL トリガー構文の詳細: トリガーは、特定のテーブル内のデータが挿入、削除、または更新される...

jsのイベントオブジェクトを深く理解しましょう

JS でよく使用されるイベントは次の通りです。ページイベント: load;フォーカス イベント: フ...

MySQL の時間設定に関する考慮事項の詳細な要約

時間は本当に存在するのでしょうか?時間は人間が考え出した概念に過ぎず、物事の変化を測る基準に過ぎない...

HTML テーブル マークアップ チュートリアル (4): 境界線の色属性 BORDERCOLOR

テーブルを美しくするために、テーブルにさまざまな境界線の色を設定できます。基本的な構文<テーブ...

スクロールラグの問題を解決するためのオーバーフロースクロールの詳細な説明

序文div またはモジュールに overflow: scroll 属性を使用すると、iOS フォンで...

IISとAPACHEはHTTPSへのHTTPリダイレクトを実装しています

7 のMicrosoft の公式 Web サイトから HTTP Rewrite モジュールをダウンロ...