以 2/4 角动态添加组件 [英] Dynamically add Component in angular 2/4

查看:22
本文介绍了以 2/4 角动态添加组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何动态添加组件?

toolbar.component.ts:

@Component({选择器:'应用程序工具栏',模板:''})导出类 ToolbarComponent {构造函数(){}}

section.component.ts:

@Component({选择器:'div[app-type=section]',模板: ''})导出类 SectionComponent {构造函数(){}}

text.component.ts:

@Component({选择器:应用文本",模板:'<p>这是动态组件</p>'})导出类 TextComponent {构造函数(){}}

view.component.ts:

@Component({选择器:'应用程序视图',模板:`<div class="container"><app-toolbar></app-toolbar><div app-type="section" id="SECTION1" class="active"></div><div app-type="section" id="SECTION2"></div>

`})导出类 SectionComponent {}

当我单击 ToolBarComponent 时,我想将 TextComponent 添加到具有活动"类的 SectionComponent.

解决方案

Expose viewContainerRef on section.component.ts:

@Component({选择器:'div[app-type=section]',模板: ''})导出类 SectionComponent {@Input() 活动:布尔值;构造函数(公共viewContainerRef:ViewContainerRef){}}

toolbar.component.ts 添加输出:

@Component({选择器:'应用程序工具栏',模板:'<button (click)="addComponentClick.emit()">添加文本组件</button>'})导出类 ToolbarComponent {@Output() addComponentClick = new EventEmitter();构造函数(){}}

view.component.ts 中为 TextComponents 创建一个 ComponentFactory 以将它们动态添加到 active SectionComponents:

import { Component, AfterViewInit, ViewChildren, QueryList, ElementRef, ComponentFactoryResolver, ComponentFactory, OnInit } from '@angular/core';import { TextComponent } from './text.component';从'./section.component'导入{SectionComponent};@成分({选择器:'应用程序视图',模板:`<div class="container"><app-toolbar (addComponentClick)="onAddComponentClick()"></app-toolbar><div app-type="section" id="SECTION1" [active]="true"></div><div app-type="section" id="SECTION2"></div>

`})导出类 ViewComponent 实现 AfterViewInit、OnInit {@ViewChildren(SectionComponent) 部分:QueryList;activeSections:SectionComponent[];textComponentFactory: ComponentFactory;构造函数(私有 componentFactoryResolver:ComponentFactoryResolver){}ngOnInit() {this.textComponentFactory = this.componentFactoryResolver.resolveComponentFactory(TextComponent);}ngAfterViewInit() {this.activeSections = this.sections.reduce((result, section, index) => {如果(部分.活动){结果.推(部分);}返回结果;}, []);}onAddComponentClick() {this.activeSections.forEach((section) => {section.viewContainerRef.createComponent(this.textComponentFactory);});}}

StackBlitz 示例

How can I add component dynamically?

toolbar.component.ts:

@Component({
  selector: 'app-toolbar',
  template: '<button>Add Text component</button>'
})
export class ToolbarComponent {
   constructor() { }
}  

section.component.ts:

@Component({
   selector: 'div[app-type=section]',
   template: ''
})
export class SectionComponent {
   constructor() { }
}  

text.component.ts:

@Component({
   selector: 'app-text',
   template: '<p>This is dynamically component</p>'
})
export class TextComponent {
   constructor() { }
}  

view.component.ts:

@Component({
   selector: 'app-view',
   template: `<div class="container">
<app-toolbar></app-toolbar>
<div app-type="section" id="SECTION1" class="active"></div>
<div app-type="section" id="SECTION2"></div>
</div>`
})
export class SectionComponent {}

when I click to ToolBarComponent, I want to add TextComponent to SectionComponent which have "active" class.

解决方案

Expose viewContainerRef on section.component.ts:

@Component({
   selector: 'div[app-type=section]',
   template: ''
})
export class SectionComponent {
  @Input() active: boolean;

   constructor(public viewContainerRef: ViewContainerRef) { }
} 

Add an output to toolbar.component.ts:

@Component({
  selector: 'app-toolbar',
  template: '<button (click)="addComponentClick.emit()">Add Text component</button>'
})
export class ToolbarComponent {
  @Output() addComponentClick = new EventEmitter();
   constructor() { }
} 

In view.component.ts create a ComponentFactory for TextComponents to add them dynamically to active SectionComponents:

import { Component, AfterViewInit, ViewChildren, QueryList, ElementRef, ComponentFactoryResolver, ComponentFactory, OnInit } from '@angular/core';
import { TextComponent } from './text.component';
import { SectionComponent } from './section.component';

@Component({
   selector: 'app-view',
   template: `<div class="container">
<app-toolbar (addComponentClick)="onAddComponentClick()"></app-toolbar>
<div app-type="section" id="SECTION1" [active]="true"></div>
<div app-type="section" id="SECTION2"></div>
</div>`
})
export class ViewComponent implements AfterViewInit, OnInit {
  @ViewChildren(SectionComponent) sections: QueryList<SectionComponent>;
  activeSections: SectionComponent[];
  textComponentFactory: ComponentFactory<TextComponent>;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {  }

  ngOnInit() {
    this.textComponentFactory = this.componentFactoryResolver.resolveComponentFactory(TextComponent);
  }

  ngAfterViewInit() {
    this.activeSections = this.sections.reduce((result, section, index) => {
      if(section.active) {
        result.push(section);
      }
      return result;
    }, []);
  }

   onAddComponentClick() {
    this.activeSections.forEach((section) => {
      section.viewContainerRef.createComponent(this.textComponentFactory);
    });
   }
}

StackBlitz example

这篇关于以 2/4 角动态添加组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆