简体   繁体   English

Angular 4删除动态添加的组件

[英]Angular 4 removing dynamically added components

Using something like this: https://netbasal.com/dynamically-creating-components-with-angular-a7346f4a982d I'm adding multiple components, the question is how do I remove the components later on based on which was clicked? 使用类似这样的内容: https : //netbasal.com/dynamically-creating-components-with-angular-a7346f4a982d我要添加多个组件,问题是如何稍后基于单击的内容删除这些组件? what I'm trying to do is create breadCrumbs, and when clicking on the crumb, remove it all all below it. 我要尝试做的是创建面包屑,然后在单击面包屑时,将其下面的所有内容全部删除。 to create them I use this code: 要创建它们,我使用以下代码:

createCrumb(name, key, level){
  let data = {name:name, key:key, level,level, diagram: this.diagram};
  const factory = this.this.resolver.resolveComponentFactory(BreadCrumbsButton);
  let componentRef = this.container.createOmponent(factory);
  (<BreadCrumbsButton>componentRef.instance).data = data;
}

all this works perfectly, but I add multiples of this. 所有这些都可以完美地工作,但是我要加倍。 the question is how do I remove specific ones while leaving the rest? 问题是如何在剩下其余部分的同时删除特定的部分?

You can call destroy method on it: 您可以在上面调用destroy方法:

  createComponent(type) {
    this.container.clear(); 
    const factory: ComponentFactory = this.resolver.resolveComponentFactory(AlertComponent);
    this.componentRef: ComponentRef = this.container.createComponent(factory);

    setTimeout(()=>{
       this.componentRef.destroy(); <--------------------
    }, 2000);
  }

I'm using a timeout here for demonstration purposes so that a component can be seen rendered on the screen. 我将超时用于演示目的,以便可以在屏幕上看到呈现的组件。

Also check this answer with Demo 同时使用演示检查此答案

Dynamically ADDING and REMOVING Components in Angular 动态添加和删除角度组件


Update 更新

You can now use subject instead of interface for components' communication 您现在可以使用subject而不是interface来进行组件的通信

Read about RxJS Subject 阅读有关RxJS主题的​​信息


Removing child components from parent so communication between them must be started but how? 从父级移除子级组件,因此必须开始它们之间的通信,但是如何进行呢?

Using interface in this case 在这种情况下使用接口

What's happening ? 发生了什么 ?

Parent is creating the childs and when a child tries to remove itself, it tells its parent via interface to remove it so the parent does. 父级正在创建子级,当子级尝试删除自己时,它会通过接口告诉其父级删除它,因此父级也会这样做。

import { ComponentRef, ComponentFactoryResolver, ViewContainerRef, ViewChild, Component } from "@angular/core";

// Parent Component
@Component({
    selector: 'parent',
    template: `
    <button type="button" (click)="createComponent()">
        Create Child
    </button>
    <div>
        <ng-template #viewContainerRef></ng-template>
    </div>
  `
})
export class ParentComponent implements myinterface {

    @ViewChild('viewContainerRef', { read: ViewContainerRef }) VCR: ViewContainerRef;

    //manually indexing the child components for better removal
    //although there is by-default indexing but it is being avoid for now
    //so index is a unique property here to identify each component individually.
    index: number = 0;

    // to store references of dynamically created components
    componentsReferences = [];

    constructor(private CFR: ComponentFactoryResolver) {
    }

    createComponent() {

        let componentFactory = this.CFR.resolveComponentFactory(ChildComponent);
        let componentRef: ComponentRef<ChildComponent> = this.VCR.createComponent(componentFactory);
        let currentComponent = componentRef.instance;

        currentComponent.selfRef = currentComponent;
        currentComponent.index = ++this.index;

        // prividing parent Component reference to get access to parent class methods
        currentComponent.compInteraction = this;

        // add reference for newly created component
        this.componentsReferences.push(componentRef);
    }

    remove(index: number) {

        if (this.VCR.length < 1)
            return;

        let componentRef = this.componentsReferences.filter(x => x.instance.index == index)[0];
        let component: ChildComponent = <ChildComponent>componentRef.instance;

        let vcrIndex: number = this.VCR.indexOf(componentRef)

        // removing component from container
        this.VCR.remove(vcrIndex);

        this.componentsReferences = this.componentsReferences.filter(x => x.instance.index !== index);
    }
}


// Child Component
@Component({
    selector: 'child',
    template: `
    <div>
    <h1 (click)="removeMe(index)">I am a Child, click to Remove</h1>
    </div>
    `
})
export class ChildComponent {

    public index: number;
    public selfRef: ChildComponent;

    //interface for Parent-Child interaction
    public compInteraction: myinterface;

    constructor() {
    }

    removeMe(index) {
        this.compInteraction.remove(index)
    }
}

// Interface
export interface myinterface {
    remove(index: number);
}

If you want to test this just create a file like comp.ts and paste that code in this file and add references to the app.module.ts 如果要进行测试,只需创建一个像comp.ts这样的文件,然后将该代码粘贴到该文件中,然后添加对app.module.ts的引用

@NgModule({
  declarations: [

    ParentComponent,
    ChildComponent

  ],
  imports: [

    //if using routing then add like so
    RouterModule.forRoot([
      { path: '', component: ParentComponent },
      { path: '**', component: NotFoundComponent }
    ]),

  ],
  entryComponents: [

    ChildComponent,  

  ],

Alternatively if you are using ViewContainerRef to hold the injected component ,you can use the clear() method . 另外,如果使用ViewContainerRef保留注入的组件,则可以使用clear()方法。

this.container.clear();

Github source Github源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM