Javascript 点击按钮,在ngfor内加载多个组件

Javascript 点击按钮,在ngfor内加载多个组件,javascript,angular,Javascript,Angular,我正在创建一个具有角度材质的项目。我想在我的项目中集成手风琴面板。在扩展面板中加载动态组件时,我遇到了一个问题。我想根据条件在扩展面板内加载不同类型的动态组件。 以下是代码: import {Component, NgModule, QueryList,ViewChildren, ComponentFactoryResolver, ViewContainerRef, TemplateRef, ViewEncapsulation} from '@angular/core' import { Tcp

我正在创建一个具有角度材质的项目。我想在我的项目中集成手风琴面板。在扩展面板中加载动态组件时,我遇到了一个问题。我想根据条件在扩展面板内加载不同类型的动态组件。 以下是代码:

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
    });
  }


  }
}
import{Component,NgModule,QueryList,ViewChildren,ComponentFactoryResolver,ViewContainerRef,TemplateRef,ViewEncapsulation}
从“@角度/核心”
从“./tcp module/tcp module.component”导入{TcpModuleComponent}
从“./udp/udp.component”导入{UdpComponent}
@组成部分({
选择器:'应用程序根',
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent{
参考:任何;
viewContainerRef=[];
@ViewChildren('target',{read:ViewContainerRef})容器:QueryList
构造函数(专用冲突解决程序:ComponentFactoryResolver){}
类别=[{
“类型”:“TCP和UDP端口”,
“代码”:“端口”,
“锁定”:false
},
{
“类型”:“DHCP”,
“代码”:“dhcp”,
“锁定”:true
},
{
“类型”:“ALG”,
“代码”:“alg”
},
{
“类型”:“Tracert”,
“代码”:“tracert”
},
{
“类型”:“带宽”,
“代码”:“带宽”
},
];
panelOpenState:boolean=false;
allExpandState=false;
恩戈尼尼特(){
console.log(this.category)
}
loadComponent(类型、项目、组件){
如果(item.locked==true){
类型。_toggle();
返回
}
让组件引用;
让零部件工厂;
如果(项目代码==“端口”){
this.container.toArray().map((viewContainerRef,i)=>{
componentFactory=this.resolver.resolveComponentFactory(TcpModuleComponent);
componentRef=viewContainerRef.createComponent(componentFactory);
this.ref=组件ref;
//this.viewContainerRef.push(viewContainerRef)
返回
});
}
如果(item.code==“dhcp”){
this.container.toArray().map((viewContainerRef,i)=>{
componentFactory=this.resolver.resolveComponentFactory(UdpComponent);
componentRef=viewContainerRef.createComponent(componentFactory);
this.ref=componentRef
返回
});
}
}
}
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 >

{{data.type}

我没有找到合适的ide来实现这一点。

您可以直接向html添加组件标记,而不是添加ng容器

<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 >

{{data.type}

您是否尝试使用角度指令来管理此问题

我认为对于您的示例,您不需要像“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)
  }   


  }
}
import{Component,NgModule,QueryList,ViewChildren,ComponentFactoryResolver,ViewContainerRef,TemplateRef,ViewEncapsulation}
从“@角度/核心”
从“./tcp module/tcp module.component”导入{TcpModuleComponent}
从“./udp/udp.component”导入{UdpComponent}
@组成部分({
选择器:'应用程序根',
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent{
参考:任何;
viewContainerRef=[];
@ViewChildren('target',{read:ViewContainerRef})容器:QueryList
构造函数(专用冲突解决程序:ComponentFactoryResolver){}
类别=[
{“类型”:“TCP&UDP端口”,“代码”:“端口”,“锁定”:false},
{“type”:“DHCP”,“code”:“DHCP”,“locked”:true},
{“类型”:“ALG”,“代码”:“ALG”},
{“类型”:“跟踪器”,“代码”:“跟踪器”},
{“类型”:“带宽”,“代码”:“带宽”},
];
panelOpenState:boolean=false;
allExpandState=false;
恩戈尼尼特(){
console.log(this.category)
}   
}
}

{{data.type}
TcpModuleComponent将在此处插入
UdpComponent将在此处插入
默认组件将插入此处


您能显示错误吗?并且您对多个项目使用了相同的id=>“#panelH”我不明白这个目的。没有错误。。我只是想知道如何在这里添加多个组件
<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>