ホームページ > ウェブフロントエンド > jsチュートリアル > Angular CDK ポータルを使用して動的コンテンツを作成する方法を段階的に説明します。

Angular CDK ポータルを使用して動的コンテンツを作成する方法を段階的に説明します。

青灯夜游
リリース: 2021-08-25 09:49:18
転載
2762 人が閲覧しました

Angular CDK ポータルを使用して動的コンテンツを作成する方法を段階的に説明します。

以前、ネイティブ API の動的ビュー挿入を紹介しましたが、この関数はすでにほとんどの使用シナリオに対応できます。ただし、Angular アプリケーションの外部にコンテンツを挿入する必要性はまだ解決されておらず、命令では動的に挿入されたコンポーネントと入出力の対話を行うことができません。

幸いなことに、Angular は、動的ビューの作成を支援する「ポータル」を含む、さまざまな Angular コンポーネントを開発するための基本ツールとして、コンポーネント開発キットのセットであるコンポーネント開発キット (CDK) を公式に提供しています。 。

この「動的ビュー」は、3 つのポータル タイプ (ComponentPortal、TemplatePortal、DomPortal) に対応するコンポーネント、TemplateRef、または DOM 要素にすることができます。これら 3 つの抽象汎用基本クラスは Portal<T> で、これには 3 つのメソッドがあります:attach (コンテナーにマウント)、detach (コンテナーからの削除)、isAttached (ビューが搭載されています))。

コンテナは、ビューと同様の抽象クラス BasePortalOutlet によっても定義され、アタッチ (ビューをコンテナにマウント)、デタッチ (ビューをコンテナから削除) が含まれます。 、dispose (コンテナを破棄)、isAttached (マウントされたビューがあるかどうか)。その主な実装は DomPortalOutlet クラスです。 3 種類のダイナミック ビューをマウントするために使用されます。

動的コンテンツの作成

まず、3 つの動的ビューの作成を見てみましょう。

ComponentPortal

ネイティブ API と比較して、動的コンポーネントの作成は非常に簡単です。コンポーネント クラスを渡すだけです。 ComponentPortal コンストラクターを使用するだけです。

this.componentPortal = new ComponentPortal(ExampleComponent);
ログイン後にコピー

任意のカスタム コンポーネント クラスを渡して ComponentPortal オブジェクトを作成し、それをビューに動的に挿入できます。

✨注: Angular 9 以降のバージョンには Ivy コンパイラを使用することをお勧めします。古いバージョンのコンパイラの場合は、渡されるコンポーネント クラスを entryComponents## で宣言する必要があります。モジュールの # およびこのモジュール 遅延読み込みはありません。

TemplatePortal

コンポーネントと比較して、TemplatePortal の構築にはパラメーター (ViewContainerRef) が 1 つ増えています。前の記事を読んだ後は、これに精通しているはずですが、埋め込みビューを作成するには、これを利用して

createEmbeddedView() を呼び出す必要があります。ここでは、コンストラクター インジェクションを通じて、現在のコンポーネントの ViewContainerRef インスタンスが直接使用されます。

<ng-template #testTemplate>
  <p>一些需要动态插入的内容.</p>
</ng-template>
ログイン後にコピー
@ViewChild(&#39;testTemplate&#39;) templatePortalContent: TemplateRef<any>;

constructor(private _viewContainerRef: ViewContainerRef) { }

ngAfterViewInit() {
  this.templatePortal = new TemplatePortal(
    this.templatePortalContent,
    this._viewContainerRef
  );
}
ログイン後にコピー

TemplatePortal には、コンストラクターに加えて、簡単に作成できるコマンド (CdkPortal) もあります。

<ng-template cdkPortal>
  <p>一些需要动态插入的内容.</p>
</ng-template>

<!-- 或写作 -->

<!-- 和上面写法是一致的效果 -->
<p *cdkPortal>
  一些需要动态插入的内容.
</p>
ログイン後にコピー

これで、

@ViewChild を通じて TemplatePortal のインスタンスを取得できます。

DomPortal

上記の例と同様に、

@ViewChild で Template インスタンスを取得して作成すると、こちらも同様にElementRefを取得して動的DOMを作成します。

<div #domPortalContent><span>原生DOM内容</span></div>
ログイン後にコピー
@ViewChild(&#39;domPortalContent&#39;) domPortalContent: ElementRef<HTMLElement>;
ngAfterViewInit() {
  this.domPortal = new DomPortal(this.domPortalContent);
}
ログイン後にコピー

この DOM は任意の場所に動的に転送できます。転送後、元のデータ バインディングまたはバインドされた命令は更新されなくなる可能性があることに注意してください。

コンテナの挿入

前の 3 種類のポータルはすべて、任意の位置にレンダリングできると述べていますが、具体的にはどのようにレンダリングすればよいでしょうか?

CdkPortOutlet

CdkPortOutlet コマンドを渡すのが最も簡単な方法です:

<div>
  <ng-template [cdkPortalOutlet]="anyPortal"></ng-template>
</div>
ログイン後にコピー

Pass to

anyPortal 上記 3 つの値のいずれかの Portal インスタンスが現在の位置に動的にレンダリングされます。

ネイティブ API 命令とは異なり、ポータルの種類を自動的に判断できます。さらに、追加のイベント

attached があり、このイベントを通じて、マウントされたコンポーネント インスタンスまたは TemplateRef を取得できます。これにより、マウントされたコンポーネントとの対話も非常に便利になります。

コンテナ インスタンスの構築

ただし、任意の場所にレンダリングできるとのことなので、当然 Angular アプリケーションの外部も含まれます。 . アプリケーションにレンダリングするには さらに、コンストラクターを通じてコン​​テナー インスタンスを作成する必要があります。

このコンテナ クラスは

DomPortalOutlet で、PortalOutlet の実装サブクラスです。その構築パラメータは主に次のとおりです: Element (マウントされたビューの DOM ノード)、ComponentFactoryResolver (前の記事と同じ、コンポーネントを動的に構築するために使用されます)、appRef (現在の Angular アプリケーションの全体的なインスタンス)、Injector (インジェクター、依存関係を渡します)。

constructor(
  private viewContainerRef: ViewContainerRef,
  @Inject(DOCUMENT) private document: any,
  private injector: Injector,
  private componentFactoryResolver: ComponentFactoryResolver
) {
  // 在<body>下创建外部宿主元素
  const container = this.document.createElement(&#39;div&#39;);
  container.classList.add(&#39;outside-portal-container&#39;);
  this.outsideContainer = this.document.body.appendChild(container);
  // 获取应用实例
  this.appRef = this.injector.get(ApplicationRef);
  // 创建外部容器
  this.outsideOutlet = new DomPortalOutlet(
    this.outsideContainer, 
    this.componentFactoryResolver, 
    this.appRef, 
    this.injector
  );
}

// 在应用外部插入动态组件。
openComponentPortalOutSideAngularContext(): void {
  const componentPortal = new ComponentPortal(AlertComponent);
  const componentRef = this.outsideOutlet.attach(componentPortal);
    componentRef.instance.closeAlert.subscribe(() => {
      this.outsideOutlet.detach();
    });
}

// 在应用外部插入动态模板。
openTemplatePortalInsideAngularContext(): void {
  const templatePortal = new TemplatePortal(this.templatePortalContent, this.viewContainerRef);
  this.outsideOutlet.attach(templatePortal);
}
ログイン後にコピー

アプリケーション外部の DOM 要素にビューをマウントすることに加えて、ビューと対話できる必要もあります。コンポーネントは依存関係を挿入でき、テンプレートはコンテキスト オブジェクトを渡すことができます。

const injectionToken = new InjectionToken<any>(&#39;Sharing data with outside component portal&#39;);
const customInjector = Injector.create({ providers: [{ provide: CustomInjectionToken, useValue: &#39;test value&#39; }] });
ログイン後にコピー

コードを少し変更して、outsideContainer を作成し、(現在のコンポーネントのインジェクターを使用する代わりに) このカスタムインジェクターをパラメーターとして渡します。

// 重点是第四个参数
new DomPortalOutlet(this.outsideContainer, this.componentFactoryResolver, this.appRef, customInjector);
ログイン後にコピー

これに応じて、このコンポーネントは次のように注入するだけで済みます。この注入トークンに依存するだけです:

constructor(@Inject(injectionToken) public customData: any) {}
ログイン後にコピー

コンテキストをテンプレートに渡すのは比較的簡単です。TemplatePortal オブジェクトを作成するときは、コンテキスト オブジェクトを渡すだけです:

// 重点是第三个参数
new TemplatePortal(this.templatePortalContent, this.viewContainerRef, { customData:&#39;test values&#39; });
ログイン後にコピー

概要

ネイティブ API と比較して、CDK ポータルは主に次の機能を実装します。

  • アプリケーションの外部にビューを動的に挿入する機能;

  • 外部に挿入されたビュー データを操作する機能;

  • より便利で柔軟な指示。

これを使用すると、動的コンポーネント コンテナー、ポップアップ ウィンドウ、フローティング メニューを作成したり、ローコード設計プラットフォームを構築したりすることも簡単になります。

プロジェクトのソース コード: https://github.com/locotor/angular-dynamic-view-example

オンラインの例: https://coding-pages-bucket-1575455 - 8137703-14801-541995-1303365836.cos-website.ap-beijing.myqcloud.com/

プログラミング関連の知識の詳細については、プログラミング入門をご覧ください。 !

以上がAngular CDK ポータルを使用して動的コンテンツを作成する方法を段階的に説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート