Angular7中动态创建带cdkDrag的div无法拖拽的问题
解决Angular7中动态生成带cdkDrag元素无法拖拽的问题
我来帮你搞定这个问题!你遇到的核心问题在于:Angular的指令(比如cdkDrag)需要经过框架的编译流程才能生效,而你直接用innerHTML或者原生DOM方式插入的HTML字符串,Angular并不会对其进行编译,所以新生成的div上的cdkDrag指令根本没被初始化,自然没法拖拽。
下面给你两种解决方案,优先推荐第一种(最符合Angular的开发模式):
方案一:用数组+*ngFor管理拖拽项(推荐)
这种方法通过Angular的结构型指令*ngFor来渲染拖拽元素,所有生成的元素都会被Angular正确编译,cdkDrag也能正常工作。
修改后的代码:
app.component.html
<div #html_container> <!-- 用*ngFor遍历products数组,每个项都带有cdkDrag指令 --> <div cdkDrag *ngFor="let product of products">{{ product }}</div> </div> <button (click)="create_element()">Add New</button>
app.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { // 初始化产品数组,默认包含Product 1 products: string[] = ['Product 1']; create_element() { // 获取后端返回的产品名(这里模拟生成) const newProduct = this.getProductName(); // 将新产品添加到数组中,Angular会自动渲染新的拖拽元素 this.products.push(newProduct); } getProductName(){ // 这里替换成你的后端服务调用,模拟随机生成产品名的逻辑 return `Product ${this.products.length + 1}`; } }
方案二:手动编译动态元素(复杂场景适用)
如果你的业务场景必须用Renderer2动态创建元素(比如非常复杂的DOM结构),那需要手动让Angular编译这些元素。不过这种方法比较繁琐,不推荐作为首选:
- 首先需要注入
ComponentFactoryResolver、ViewContainerRef等依赖; - 创建一个简单的拖拽项组件(比如
DragItemComponent),里面包含带cdkDrag的div; - 通过组件工厂动态创建这个组件,并添加到容器中。
不过这种方法代码量更大,维护成本高,所以优先用方案一就足够解决你的问题了。
你原来代码的几个问题点:
this.render2.createElement('html_container')是错误的:html_container是模板中的变量名,不是HTML标签,你应该创建div元素;- 直接用
innerHTML插入带指令的HTML,Angular不会编译这些指令,导致cdkDrag失效。
内容的提问来源于stack exchange,提问作者Gopal
相关产品推荐
相关产品推荐

