微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

html – 动态添加和删除Angular中的组件

目前的官方文档仅显示如何动态更改< ng-template>中的组件.标签. https://angular.io/guide/dynamic-component-loader

我想要实现的是,假设我有3个组件:标题,节和页脚,带有以下选择器:

<app-header>
<app-section>
<app-footer>

然后有6个按钮可以添加删除每个组件:添加标题,添加节和添加页脚

当我点击添加标题时,该页面添加< app-header>到呈现它的页面,所以页面将包含:

<app-header>

然后如果我单击Add Section两次,该页面现在将包含:

<app-header>
<app-section>
<app-section>

如果单击“添加页脚”,页面将包含所有这些组件:

<app-header>
<app-section>
<app-section>
<app-footer>

是否有可能在Angular中实现这一目标?请注意,ngFor不是我正在寻找的解决方案,因为它只允许向页面添加相同的组件,而不是不同的组件.

编辑:ngIf和ngFor不是我正在寻找的解决方案,因为模板已经预先确定.我正在寻找的东西就像是一堆组件或一组组件,我们可以轻松地添加,删除和更改数组的任何索引.

编辑2:为了使它更清楚,让我们有另一个例子说明为什么ngFor不起作用.假设我们有以下组件:

<app-header>
<app-introduction>
<app-camera>
<app-editor>
<app-footer>

现在,这里有一个新组件< app-description>,用户希望在其中插入< app-editor>. ngFor只有在我想要循环遍历的同一个组件时才有效.但是对于不同的组件,ngFor在这里失败了.

解决方法

您可以通过使用ComponentFactoryResolver动态创建组件然后将它们注入ViewContainerRef来完成您要实现的目标.动态执行此操作的一种方法是将组件的类作为函数的参数传递,该函数将创建并注入组件.

见下面的例子:

import {
  Component,ComponentFactoryResolver,Type,ViewChild,ViewContainerRef
} from '@angular/core';

// Example component (can be any component e.g. app-header app-section)
import { DraggableComponent } from './components/draggable/draggable.component';

@Component({
  selector: 'app-root',template: `
    <!-- Pass the component class as an argument to add and remove based on the component class -->
    <button (click)="addComponent(draggableComponentClass)">Add</button>
    <button (click)="removeComponent(draggableComponentClass)">Remove</button>

    <div>
      <!-- Use ng-template to ensure that the generated components end up in the right place -->
      <ng-template #container>

      </ng-template>
    </div>

  `
})
export class AppComponent {
  @ViewChild('container',{read: ViewContainerRef}) container: ViewContainerRef;

  // Keep track of list of generated components for removal purposes
  components = [];

  // Expose class so that it can be used in the template
  draggableComponentClass = DraggableComponent;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {
  }

  addComponent(componentClass: Type<any>) {
    // Create component dynamically inside the ng-template
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentClass);
    const component = this.container.createComponent(componentFactory);

    // Push the component so that we can keep track of which components are created
    this.components.push(component);
  }

  removeComponent(componentClass: Type<any>) {
    // Find the component
    const component = this.components.find((component) => component.instance instanceof componentClass);
    const componentIndex = this.components.indexOf(component);

    if (componentIndex !== -1) {
      // Remove component from both view and array
      this.container.remove(this.container.indexOf(component));
      this.components.splice(componentIndex,1);
    }
  }
}

笔记:

>如果您希望以后更容易删除组件,可以在局部变量中跟踪它们,请参阅this.components.或者,您可以遍历ViewContainerRef中的所有元素.
>您必须将组件注册为条目组件.在模块定义中,将组件注册为entryComponent(entryComponents:[DraggableComponent]).

运行示例:
https://plnkr.co/edit/mrXtE1ICw5yeIUke7wl5

了解更多信息:
https://angular.io/guide/dynamic-component-loader

原文地址:https://www.jb51.cc/html/231967.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐