Angular2+Gridster2中为动态添加元素注入动态组件的技术问询
在Angular Gridster2中动态加载组件到新增网格项
我来帮你搞定这个动态组件加载的问题,结合你现有的代码结构,咱们一步步来实现:
1. 先更新数据结构,存储组件类型
原来的dashboard数组只保存了网格尺寸,现在得把组件类型也加进去,这样每个网格项才能明确要加载哪个组件。修改你的add方法:
add(size: string, type: string){ size = size || 'default'; const newSize = this.sizeOptions[size]; if(!this.gridElements.options.api.getNextPossiblePosition(newSize)) { alert('hey, no can do, buddy!'); return false; } // 新增组件类型字段,同时加个唯一ID避免ngFor追踪问题 const newItem = { ...newSize, componentType: type, id: new Date().getTime() }; this.dashboard.push(newItem); this.gridElements.changeGrid(this.dashboard); }
2. 创建动态组件加载容器
咱们需要一个通用组件,作为每个gridster-item里的动态组件容器。新建DynamicComponentLoaderComponent:
import { Component, Input, ViewChild, ViewContainerRef, ComponentFactoryResolver, OnChanges, SimpleChanges } from '@angular/core'; // 导入你要动态加载的所有目标组件 import { Comp1Component } from './comp1/comp1.component'; import { Comp2Component } from './comp2/comp2.component'; // 建立组件类型与组件类的映射表 const COMPONENT_MAP = { comp1: Comp1Component, comp2: Comp2Component }; @Component({ selector: 'app-dynamic-component-loader', template: `<div #container></div>` }) export class DynamicComponentLoaderComponent implements OnChanges { @Input() componentType: string; @ViewChild('container', { read: ViewContainerRef, static: false }) container: ViewContainerRef; constructor(private resolver: ComponentFactoryResolver) {} ngOnChanges(changes: SimpleChanges): void { // 当组件类型变化时,重新加载组件 if (changes.componentType && this.componentType) { this.loadTargetComponent(); } } private loadTargetComponent(): void { this.container.clear(); // 先清空容器旧内容 const targetComponent = COMPONENT_MAP[this.componentType]; if (!targetComponent) return; const factory = this.resolver.resolveComponentFactory(targetComponent); this.container.createComponent(factory); } }
3. 修改Gridster项模板,加入动态容器
在你的gridster-item模板里插入这个动态加载容器,绑定item的componentType字段:
<div id="grid"> <gridster [options]="options"> <gridster-item [item]="item" *ngFor="let item of dashboard;let i = index;" [id]="item.id"> <div class="grid-header drag-handle"> <span class="handle-icon"><i class="material-icons">open_with</i></span> <span class="close-icon" (click)="removePanel(item)"><i class="material-icons">close</i></span> </div> <!-- 新增动态组件加载容器 --> <app-dynamic-component-loader [componentType]="item.componentType"></app-dynamic-component-loader> </gridster-item> </gridster> </div>
4. 模块配置(关键步骤)
在你的模块里,要把动态加载的组件、加载容器都声明好。如果是Angular 9之前的版本,还需要把动态组件加入entryComponents:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { GridComponent } from './grid/grid.component'; import { DynamicComponentLoaderComponent } from './dynamic-component-loader/dynamic-component-loader.component'; import { Comp1Component } from './comp1/comp1.component'; import { Comp2Component } from './comp2/comp2.component'; import { GridsterModule } from 'angular-gridster2'; @NgModule({ declarations: [ GridComponent, DynamicComponentLoaderComponent, Comp1Component, Comp2Component ], imports: [ CommonModule, GridsterModule ], // Angular 9+ 可省略entryComponents,旧版本必须添加 entryComponents: [Comp1Component, Comp2Component] }) export class GridModule { }
5. 调整导航组件的点击事件
现在你可以在app-navigation里的点击事件中传入组件类型了:
<!-- 示例:点击添加不同尺寸和类型的组件 --> <button (click)="add('large','comp1')">添加大尺寸组件1</button> <button (click)="add('default','comp2')">添加默认尺寸组件2</button>
如果后续需要给动态组件传递数据,可以在DynamicComponentLoaderComponent里新增@Input() componentData,然后在创建组件时通过componentRef.instance.data = this.componentData来传值。
内容的提问来源于stack exchange,提问作者dcp3450
相关产品推荐
相关产品推荐

