cdkDrag搭配cdkDragBoundary嵌套自定义组件时无法自由拖拽怎么办
问题根因
这不是cdkDragBoundary的兼容性问题,是自定义组件默认渲染行为导致的边界计算逻辑异常:
- Angular自定义组件的宿主标签(即
<app-tabletop-creator-placeable>)默认是display: inline行内元素,本身不具备独立宽高、定位上下文 - 你把绝对定位、200*200的宽高样式都写在了组件内部的
.example-placable子div上,cdkDragBoundary计算可移动范围时,默认读取cdkDrag节点下直接子元素的占位尺寸、初始偏移值:- 子元素是普通div时,能正确读到宽高和初始位置,边界计算正常
- 子元素是自定义组件宿主标签时,读到的是行内元素的0宽度、水平偏移0,直接把水平方向可移动距离算成0,自然只能上下拖
- 移除cdkDragBoundary时不需要做范围校验,所以全方向拖拽不受影响,和你观察到的现象完全吻合。
修复方法
任选一种即可解决:
- 方案1(推荐,最符合组件封装逻辑):给自定义组件宿主元素绑定正确的显示模式和样式,在
TabletopCreatorPlaceableComponent的@Component装饰器里加host配置:
@Component({ selector: 'app-tabletop-creator-placeable', templateUrl: './tabletop-creator-placeable.component.html', styleUrls: ['./tabletop-creator-placeable.component.css'], host: { 'class': 'example-placable', 'style': 'display: block;' } })
把组件内部模板的外层div去掉即可,cdkDrag可以直接从宿主元素读到正确的尺寸、位置,边界计算就正常了。
- 方案2(改动最小):直接把cdkDrag指令移到自定义组件标签上,去掉多余的嵌套div:
<main> <div class="example-boundary"> <app-tabletop-creator-placeable cdkDrag cdkDragBoundary=".example-boundary"> </app-tabletop-creator-placeable> </div> </main>
额外给宿主元素加个display: block样式就行,可以写在组件host配置里,也可以写在全局样式表中。
- 方案3(不改组件代码):给包裹cdkDrag的空div设置和内部拖拽元素一致的尺寸、定位:
div[cdkDrag] { width: 200px; height: 200px; position: absolute; }
cdkDrag从外层div读到正确的尺寸参数,边界计算也能恢复正常。
改完之后拖拽时检查元素transform属性,水平方向translate值不再被锁死为0,就可以在边界范围内全方向自由移动了。
内容的提问来源于stack exchange,提问作者Brandon Steele
相关产品推荐
相关产品推荐

