使用Angular时动态添加组件
我将介绍如何在点击按钮时动态插入Angular组件。
我将以下内容分成两部分进行解释。
-
- 将Angular组件动态插入(→首先在不考虑位置的情况下插入)
- 在特定位置动态插入Angular组件
步骤1:动态插入Angular组件
创建能够动态插入的组件
在这里,我们将创建以下非常简单的组件。
...
import { Component } from '@angular/core';
@Component({
selector: 'app-dynamic',
template: `<p>dynamic works!</p>`
})
export class DynamicComponent {
}
在HTML上放置按钮。
点击按钮后,将执行onButtonClick()方法,并能够生成Angular组件。
...
<div>
<button (click)="onButtonClick()">click!</button>
</div>
以动态方式插入Angular组件
使用ComponentFactory和viewContainerRef,将Angular组件插入。
-
- 初期処理 ngOnInit() で、動的に DynamicComponent をコンパイルできる状態にします。
- クリックされた時に、 viewContainerRef.createComponent を利用し、コンポーネント生成を実行します。
...
import { Component, ComponentFactory, ComponentFactoryResolver, OnInit, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic/dynamic.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
factory: ComponentFactory<DynamicComponent>;
constructor(
public viewContainerRef: ViewContainerRef,
private resolver: ComponentFactoryResolver) { }
ngOnInit() {
this.factory = this.resolver.resolveComponentFactory(DynamicComponent);
}
onButtonClick() {
this.viewContainerRef.createComponent(this.factory);
}
}
在@NgModule.entryComponents中添加动态插入的组件。
(3) 实现到(3)阶段,当点击按钮时,将显示错误信息:“未找到DynamicComponent的组件工厂。您是否将其添加到@NgModule.entryComponents中?”
按照指示添加entryComponents后,当按下按钮时,将完成动态显示Angular组件的过程。
...
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DynamicComponent } from './dynamic/dynamic.component';
@NgModule({
declarations: [
AppComponent,
DynamicComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [DynamicComponent] // Add entryComponents here!
})
export class AppModule { }
请在此处查看整个源代码的确认。
第二步,動態地將Angular組件插入到特定位置。
在假设 Step1 已完成的前提下,使用 @ViewChild 可以指定组件的放置位置。需要分别编辑 component.ts 和 html 文件。
...
export class AppComponent implements OnInit {
factory: ComponentFactory<DynamicComponent>;
// @ViewChild を追加
@ViewChild('dynamic', { read: ViewContainerRef }) viewContainerRef: ViewContainerRef;
// 不要になった ViewContainerRef をコンストラクタから削除
constructor(
private resolver: ComponentFactoryResolver) { }
(以下略)
在HTML中,我们可以在希望插入组件的位置上添加上述的 @ViewChild 定义的 #dynamic 标签。以下示例将确保组件在按钮上方生成。
...
<div #dynamic></div>
<div>
<button (click)="onButtonClick()">click!</button>
</div>
在完成上述操作后,点击按钮,可以确认在按钮上显示”dynamic works!”。
请点击这里查看整个源代码。
填補缺失的部分
-
- 今回の実装ではDOM要素を追加しているだけなので、DomSanitizerを利用して実装することもできます。
- コンポーネントを生成するロジックをServiceクラスに置くことで、ほかのコンポーネントから呼び出すことができるようにできます。詳しくは「参考」に載せているページで確認できます。
请提供一份参考。
-
- Dynamically add Component in angular 2/4 – Stack Overflow
-
- Angularで中身を動的に変えられるModalを作る【基本編】 – Carpe Diem
-
- Dynamically add components to the DOM with Angular – Frontend Weekly – Medium
- ionic framework – What is entryComponents in angular ngModule? – Stack Overflow