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内部属性,通用性更强:
- 给列组件的DOM元素加一个自定义属性,把你的列对象ID绑定上去:
<app-column [attr.data-column-id]="yourColumnObject.id" [columnData]="yourColumnObject"></app-column>
- 在父组件里维护一个列对象的映射表,把所有列对象按ID存起来:
// 假设你的列对象类型是Column columnMap: Map<number, Column> = new Map(); ngOnInit() { // 初始化时把所有列存入映射表 this.yourColumnList.forEach(column => { this.columnMap.set(column.id, column); }); }
- 在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
相关产品推荐
相关产品推荐

