You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 4中ng2-dragula如何获取源/目标Angular对象而非DOM元素?

解决ng2-dragula中获取源/目标Angular对象的问题

我之前在Angular 4里用ng2-dragula做跨列拖拽的时候也碰到过这个需求,当时试了几种方法,这里分享两个最靠谱的:

方法一:从DOM元素直接获取Angular组件实例

ng2-dragula返回的source和target是真实的DOM节点,而Angular会把组件实例绑定在对应的DOM元素上。你可以这么操作:

首先,给你的列组件(比如<app-column>)在模板里加个模板引用变量:

<app-column #columnComp [columnData]="yourColumnObject"></app-column>

然后在drop事件的回调里,通过DOM元素获取组件实例:

this._dragulaEventSubscription.add(this._dragulaService.dropModel(id)
.subscribe(({ source, target }) => {
  // 从源DOM元素拿到对应的Angular组件实例
  const sourceComp = source['__ngContext__']?.find(ctx => ctx.component)?.component;
  // 拿到组件绑定的数据源对象
  const sourceColumnObj = sourceComp?.columnData;

  // 同理处理目标列
  const targetComp = target['__ngContext__']?.find(ctx => ctx.component)?.component;
  const targetColumnObj = targetComp?.columnData;

  console.log('源列对象:', sourceColumnObj);
  console.log('目标列对象:', targetColumnObj);
})
);

注意:__ngContext__是Angular 4的内部属性,虽然当时能用,但如果后续版本升级可能会失效。如果担心这个,用下面的方法二更稳妥。

方法二:通过自定义属性+映射表关联DOM与Angular对象

这个方法不依赖Angular内部属性,通用性更强:

  1. 给列组件的DOM元素加一个自定义属性,把你的列对象ID绑定上去:
<app-column [attr.data-column-id]="yourColumnObject.id" [columnData]="yourColumnObject"></app-column>
  1. 在父组件里维护一个列对象的映射表,把所有列对象按ID存起来:
// 假设你的列对象类型是Column
columnMap: Map<number, Column> = new Map();

ngOnInit() {
  // 初始化时把所有列存入映射表
  this.yourColumnList.forEach(column => {
    this.columnMap.set(column.id, column);
  });
}
  1. 在drop事件里,从DOM元素取出ID,再从映射表中拿到对应的Angular对象:
this._dragulaEventSubscription.add(this._dragulaService.dropModel(id)
.subscribe(({ source, target }) => {
  // 获取源列ID并取出对应对象
  const sourceId = parseInt(source.getAttribute('data-column-id'), 10);
  const sourceColumnObj = this.columnMap.get(sourceId);

  // 获取目标列ID并取出对应对象
  const targetId = parseInt(target.getAttribute('data-column-id'), 10);
  const targetColumnObj = this.columnMap.get(targetId);

  console.log('源列对象:', sourceColumnObj);
  console.log('目标列对象:', targetColumnObj);
})
);

这个方法我当时用下来最稳定,哪怕后续升级Angular版本也不会受影响,完全不需要用随机ID,直接用你列对象本身的唯一ID就行(比如业务里的主键ID)。

内容的提问来源于stack exchange,提问作者Crocsx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:00:05