我发现了this的使用闪电cdk将拖放添加到mat-table的stackblitz示例。但是,所需的行为是该行只能使用带有cdkDragHandle指令的元素进行拖动。在此示例中,您可以通过单击行上的任意位置来拖动元素。该如何修改,以使该行只能使用拖动手柄进行拖动?
答案 0 :(得分:4)
这是我针对此问题的解决方法:
cdkDrag
。默认行为已禁用。mousedown
添加mouseup
,touchstart
,touchend
和cdkDragHandle
事件处理程序以切换控件。cdkDrag
中,监听cdkDragReleased
事件以将cdkDrag
拖动后禁用。副作用是,使用真正要禁用的项目变得更加困难(例如,对那些真正禁用的项目应用样式)。
代码如下:
dragDisabled = true;
<mat-row
*matRowDef="let row; columns: displayedColumns"
cdkDrag
[cdkDragData]="row"
[cdkDragDisabled]="dragDisabled"
(cdkDragReleased)="dragDisabled = true"
></mat-row>
<mat-icon
cdkDragHandle
(touchstart)="dragDisabled = false"
(touchend)="dragDisabled = true"
(mousedown)="dragDisabled = false"
(mouseup)="dragDisabled = true"
>drag_indicator</mat-icon
>
答案 1 :(得分:1)
恕我直言,除了破解/覆盖Angular Material / CDK的源代码外,没有其他快速解决方案。对此的证明是在github上的开放功能请求:https://github.com/angular/material2/issues/13770。
问题在于,数据源/ MatTable上的cdkDrag会在所有子元素上自动创建拖动注释(这会生成行为),并且无法(轻松)覆盖。
基于文档cdkDrag/cdkDragDisabled
-cdkDragHandle/cdkDragHandleDisabled
应该有所帮助(它确实可以在没有表的情况下工作)。我已经升级了示例中的所有库以支持它们,但没有任何效果。
答案 2 :(得分:1)
对于这个复杂的问题,我发现了一个简单的问题。对于可拖动tr中的任何简单文本td,我们可以使用指标事件:无,它将禁用所有文本元素。
在手柄图标上,使用pointer-events:all,它将仅允许从该图标拖动。
这还有一个问题,它禁用了所有锚点和按钮。因此,对于图标和按钮,进行以下操作
检查此stackblits的有效答案 https://stackblitz.com/edit/angular-rwzc76
答案 3 :(得分:1)
我在这里有一个替代答案(以前可能不可能) - 它结合了 @H Dog
和 @Mamoon ur Rasheed
的答案。
根据 H Dog 的回答,将拖动手柄移动到单元格本身而不是行中,并使用 cdkDragRootElement
选择父垫行。但是,这仍然使整行可拖动。
接下来,默认禁用拖动,绑定到组件上的布尔值。当在拖动手柄上触发 mousedown 事件时,启用拖动,然后在下一帧中再次禁用它。
这使得整行允许正常交互,但允许通过具有适当占位符和预览功能的拖动手柄拖动。
答案 4 :(得分:0)
我通过将Vectors do not all have the same length. SNP LDL-c.beta LDL-c.se CHD.beta CHD.se
1 snp_10 1 0.004 2 0.0286
2 snp_10 1 0.004 2 0.0300
3 snp_10 1 0.004 2 0.0310
4 snp_10 1 0.003 2 0.0243
5 snp_10 1 0.003 2 0.0222
6 snp_10 1 0.006 2 0.0667
应用于dragHandle本身而不是行,并使用cdkDrag
来标识该行,从而实现了UX。它可以实现通过手柄拖动的UX,但是仍然存在一个错误,无法在放下后实际重新排序。
答案 5 :(得分:0)
对于这里发布的解决方案,我有另一种解决方案。除了链接和纯文本单元格需要更多的交互性(包括文本选择,输入字段等)外,我还有一个要求。
使用将在cdkDrag
表行(tr
)中呈现的所有不可拖动单元格上的指令,我能够阻止mousedown
事件冒泡到cdkDrag
实例的有效cdkDropList
行。
这是我的指令最终看起来像的样子。
import {Directive, ElementRef, OnDestroy, OnInit} from '@angular/core';
@Directive({
selector: '[appCancelCdkDrag]'
})
export class CancelCdkDrag implements OnInit, OnDestroy {
$element: HTMLElement;
constructor(el: ElementRef) {
this.$element = el.nativeElement;
}
fireMouseUp($event: MouseEvent) {
$event.cancelBubble = true;
}
ngOnDestroy(): void {
this.$element.removeEventListener('mousedown', this.fireMouseUp);
}
ngOnInit(): void {
this.$element.addEventListener('mousedown', this.fireMouseUp);
}
}
此处的StackBlitz:https://stackblitz.com/edit/angular-tgrcni
以下是有关Github Angular Components页面的相关评论:https://github.com/angular/components/issues/13770#issuecomment-553193486
希望这会有所帮助。
答案 6 :(得分:0)
这是一个仅按特定列开始拖动行的示例:
在组件上创建一个变量
dragEnabled = false;
将行设置为可拖动并通过变量禁用拖动
<mat-row *matRowDef="let row; columns: columns;" cdkDrag [cdkDragDisabled]="!dragEnabled">
</mat-row>
通过鼠标事件控制特定列上的dragEnabled变量状态
<ng-container matColumnDef="drag">
<mat-header-cell *matHeaderCellDef>
</mat-header-cell>
<mat-cell *matCellDef="let entity"
(mouseenter)="dragEnabled = true"
(mouseleave)="dragEnabled = false">
<mat-icon>
drag_indicator
</mat-icon>
</mat-cell>
</ng-container>
现在您可以选择行内容并仅按特定列拖动行。