【问题标题】:Load multiple components inside ngfor on click of button单击按钮在 ngfor 中加载多个组件
【发布时间】:2020-05-25 13:17:50
【问题描述】:

我正在使用 Angular-Material 创建一个项目。我想在我的项目中集成手风琴面板。在扩展面板中加载动态组件时遇到问题。我想根据条件在扩展面板内加载动态不同类型的组件。 这是代码:

import {Component, NgModule, QueryList,ViewChildren, ComponentFactoryResolver, ViewContainerRef, TemplateRef, ViewEncapsulation}
from '@angular/core'
import { TcpModuleComponent } from './tcp-module/tcp-module.component'
import { UdpComponent } from './udp/udp.component'
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  ref:any;
  viewContainerRef = [];
  @ViewChildren('target', {read: ViewContainerRef}) container: QueryList<ViewContainerRef>

  constructor(private resolver: ComponentFactoryResolver) {}

  category = [{
    "type":"TCP&UDP Port",
    "code":"port",
    "locked":false
  },
  {
    "type":"DHCP",
    "code":"dhcp",
    "locked":true
  },
  {
    "type":"ALG",
    "code":"alg"
  },
  {
    "type":"Tracert",
    "code":"tracert"
  },
  {
    "type":"Bandwidth",
    "code":"bandwidth"
  },
];
  panelOpenState: boolean = false;
  allExpandState = false;
  ngOnInit() {
    console.log(this.category)
  }
  loadComponent(type,item,comp){
    if(item.locked == true){
      type._toggle();
      return
    }

    let componentRef;
    let componentFactory;


    if(item.code == "port"){
      this.container.toArray().map((viewContainerRef, i) => {
        componentFactory = this.resolver.resolveComponentFactory(TcpModuleComponent);  
        componentRef = viewContainerRef.createComponent(componentFactory);
        this.ref = componentRef;
      // this.viewContainerRef.push(viewContainerRef)
        return
      });
    }
    if(item.code == "dhcp"){
      this.container.toArray().map((viewContainerRef, i) => {
      componentFactory = this.resolver.resolveComponentFactory(UdpComponent);  
      componentRef = viewContainerRef.createComponent(componentFactory);
      this.ref = componentRef
      return
    });
  }


  }
}

HTML部分

<mat-accordion >
<mat-expansion-panel *ngFor="let data of category" (click)="loadComponent(panelH,data)">
  <mat-expansion-panel-header #panelH >
    <mat-panel-title>
    <span class="title">{{data.type}}</span>
      </mat-panel-title>
  </mat-expansion-panel-header>
  <div *ngIf="data.code == 'port'">
    <ng-container #target></ng-container>
  </div>
</mat-expansion-panel>
</mat-accordion >

我没有正确的想法来实现这一目标。

【问题讨论】:

  • 你能显示错误吗?
  • 而且您对多个项目使用相同的 id=> '#panelH' 我不明白这个目的。
  • 没有错误..我只是想知道这里如何添加多个组件

标签: javascript angular


【解决方案1】:

您可以直接将组件标签添加到html中,而不是添加ng-container。

<mat-accordion >
<mat-expansion-panel *ngFor="let data of category" (click)="loadComponent(panelH,data)">
  <mat-expansion-panel-header #panelH >
    <mat-panel-title>
    <span class="title">{{data.type}}</span>
      </mat-panel-title>
  </mat-expansion-panel-header>
  <TcpModuleComponent *ngIf="data.code === 'port'"></TcpModuleComponent>
  <UdpComponent*ngIf="data.code === 'dhcp'"></UdpComponent>
</mat-expansion-panel>
</mat-accordion >

【讨论】:

    【解决方案2】:

    您是否尝试使用 Angular 指令来管理它? Angular Directives

    而且我认为对于您的示例,您不需要像“LoadComponent”这样的点击事件。 请看以下示例:

    import {Component, NgModule, QueryList,ViewChildren, ComponentFactoryResolver, ViewContainerRef, TemplateRef, ViewEncapsulation}
    from '@angular/core'
    import { TcpModuleComponent } from './tcp-module/tcp-module.component'
    import { UdpComponent } from './udp/udp.component'
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      ref:any;
      viewContainerRef = [];
      @ViewChildren('target', {read: ViewContainerRef}) container: QueryList<ViewContainerRef>
    
      constructor(private resolver: ComponentFactoryResolver) {}
    
      category = [
        { "type": "TCP&UDP Port", "code": "port", "locked": false },
        { "type": "DHCP", "code": "dhcp", "locked": true },
        { "type": "ALG", "code": "alg" },
        { "type": "Tracert", "code": "tracert" },
        { "type": "Bandwidth", "code": "bandwidth" },
      ];
      panelOpenState: boolean = false;
      allExpandState = false;
      ngOnInit() {
        console.log(this.category)
      }   
    
    
      }
    }
    
    <div class="row">
          <div class="col-md-12 mt-5 ml-5">
            <mat-accordion>
              <mat-expansion-panel *ngFor="let data of category">
                <mat-expansion-panel-header>
                  <mat-panel-title>
                    <span class="title">{{data.type}}</span>
                  </mat-panel-title>
                </mat-expansion-panel-header>
                <span [ngSwitch]="data.code">
                  <div *ngSwitchCase="'port'">
                    TcpModuleComponent will insert here
                  </div>
                  <div *ngSwitchCase="'dhcp'">
                     UdpComponent will insert here
                  </div>
                  <div *ngSwitchDefault>
                     Default component will insert here 
                  </div>
                </span>
             </mat-expansion-panel>
          </mat-accordion>
       </div>
    </div>
    

    【讨论】:

      猜你喜欢
      • 2020-06-13
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 2020-03-13
      • 1970-01-01
      相关资源
      最近更新 更多