在Angular2中生成动态组件

以下是使用Angular2动态生成组件的示例代码。

sample-capture-edit.png

确认操作的环境

    Plunker (Angular-2.3.0)

源代码

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import {
  Component,
  ComponentFactoryResolver,
  EventEmitter,
  NgModule,
  OnInit,
  OnDestroy,
  ViewContainerRef
} from '@angular/core';
import { Observable } from 'rxjs/Rx'; // MEMO: plunkerの場合は'rxjs/Rx'、ローカルでangular-cliの場合は'rxjs'


/**
 * 動的に生成するサンプルコンポーネント
 */
@Component({
  selector: 'app-sample',
  template: `
    <div style="margin: 1rem; padding: 1rem; border: 1px solid #eee;">
      <button (click)="closeButton_Clicked()">CLOSE</button> No. {{_no}}
    </div>
  `,
})
export class SampleComponent implements OnInit, OnDestroy
{
  /** クローズイベント */
  private _closing = new EventEmitter<{}>();

  /** コンポーネント生成元から受け取るパラメータ */
  private _no: number = 0;

  /** クローズイベントのgetプロパティ */
  public get closing(): Observable<{}>
  {
    return this._closing;
  }

  /** コンポーネント生成元から受け取るパラメータのsetプロパティ */
  public set no(value: number)
  {
    this._no = value;
  }

  /**
   * Angular Lifecycle Hooks: OnInit
   */
  public ngOnInit(): void
  {
    console.log(`SampleComponent.ngOnInit >> no="${this._no}"`);
  }

  /**
   * Angular Lifecycle Hooks: OnDestroy
   */
  public ngOnDestroy(): void
  {
    console.log(`SampleComponent.ngOnDestroy >> no="${this._no}"`);
  }

  /**
   * CLOSEボタンのクリックイベントハンドラ
   */
  private closeButton_Clicked(): void
  {
    // クローズイベントを発行
    this._closing.emit({});
  }
}


/**
 * メインAppコンポーネント
 */
@Component({
  selector: 'my-app',
  template: `
    <div style="padding: 1rem; border: 1px solid #eee;">
      <h2>Angular2 Dynamic Component Sample</h2>
      <button (click)="createButton_Clicked()">CREATE</button>
    </div>
  `,
})
export class App
{
  public constructor(
    private _componentFactoryResolver: ComponentFactoryResolver,
    private _viewContainerRef: ViewContainerRef)
  {
  }

  /**
   * CREATEボタンのクリックイベントハンドラ
   */
  private createButton_Clicked(): void
  {
    // コンポーネント生成器を初期化
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(SampleComponent);

    // 動的にコンポーネントを生成
    const componentRef = this._viewContainerRef.createComponent(componentFactory);

    // 動的に生成したコンポーネントにパラメータを渡す
    componentRef.instance.no = Math.floor(Math.random() * 100); // 0~99のランダム値を渡す

    // closingイベントを受けたらコンポーネント破棄する
    componentRef.instance.closing.subscribe(() => {
      componentRef.destroy();
    });
  }
}


/**
 * アプリケーションモジュール
 */
@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, SampleComponent ], // 独自のcomponent/directiveをdeclarationsに指定する
  bootstrap: [ App ],
  entryComponents: [ SampleComponent ], // 動的に生成するcomponentをentryComponentsに指定する
})
export class AppModule
{
}

platformBrowserDynamic().bootstrapModule(AppModule);
广告
将在 10 秒后关闭
bannerAds