限制 angular 中两个不可拖动项之间的拖放
restricting drag and drop between two non-dragable items in angular
我正在制作一个 angular 应用程序,其中有两个列表。从列表 'A',我可以一次又一次地 复制 项目到列表 'B'。问题是,我想让拖动的项目只添加到列表 'B' 中的开始和结束项目之间。 see image
这是我目前尝试过的方法:
HTML:
<mat-drawer-container class="example-container">
<mat-drawer mode="side" opened>
<h3>Create your Workflow</h3>
<h5>Drag and drop the elements to visualize the process.</h5>
<div cdkDropList
#optionsList="cdkDropList"
[cdkDropListData]="options"
[cdkDropListConnectedTo]="[workflowList]"
class="example-list"
cdkDropListSortingDisabled
(cdkDropListDropped)="drop($event)"
[cdkDropListEnterPredicate]="noReturnPredicate">
<div class="example-box" cdkDrag *ngFor="let item of options"> {{item}} </div>
</div>
</mat-drawer>
<mat-drawer-content>
<div cdkDropList
#workflowList="cdkDropList"
[cdkDropListData]="workflow"
[cdkDropListConnectedTo]="[optionsList]"
class="example-list"
(cdkDropListDropped)="drop($event)"
[cdkDropListSortPredicate]="sortPredicate"
>
<div class="example-box" [cdkDragDisabled]="item.disabled" *ngFor="let item of workflow" cdkDragLockAxis="y" cdkDrag>{{item.value}}</div>
</div>
</mat-drawer-content>
.ts -> 导出 class:
options = [
'Step',
'Branch'
];
workflow=[
{value: 'Start', disabled: true},
{value: 'Finish', disabled: true}
];
drop(event: any) {
if (event.previousContainer === event.container) {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
} else {
copyArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
}
}
noReturnPredicate(){
return false;
}
sortPredicate(){
return false;
}
现在我只能在工作流程中输入'End'之后的选项。我希望它在开始和结束之间。有人可以帮忙吗?
另外,添加的列表中没有显示选项名称,如果有人能在这方面指导我,那将非常有帮助。谢谢
我在 drop 方法中使用了如下条件:
event.currentIndex>0 && event.currentIndex<this.workflow.length
有两个问题:
两个下拉列表应具有相同的值类型。你有:
options: string[],
workflow: {value: string, disabled: boolean}[],
所以,你应该统一类型(或者写你自己的 copyArrayItem
方法来在类型之间转换):
interface DragItem {
value: string;
disabled: boolean;
}
...
options: DragItem[] = [
{ value: 'Step', disabled: ... },
{ value: 'Branch', disabled: ... }
];
workflow: DragItem[] = [
{ value: 'Start', disabled: true },
{ value: 'Finish', disabled: true }
];
如果你想让索引保持在定义的范围内,检查它:
sortPredicate(index: number, drag: CdkDrag, drop: CdkDropList): boolean {
// preliminary check, not reliable
return index > 0 && index < drop.getSortedItems().length;
}
sortPredicate
实际上是不可靠的(我可以将项目放置在禁止位置),你应该仔细检查 drop 事件中的索引行为并修复它:
drop(event: CdkDragDrop<DragItem[], any>) {
if (event.previousContainer === event.container) {
moveItemInArray(
event.container.data,
event.previousIndex,
event.currentIndex
);
} else {
let currentIndex = event.currentIndex;
// double check index range
if (0 === currentIndex) {
currentIndex++;
}
if (event.container.getSortedItems().length === currentIndex) {
currentIndex--;
}
copyArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
currentIndex
);
}
}
我正在制作一个 angular 应用程序,其中有两个列表。从列表 'A',我可以一次又一次地 复制 项目到列表 'B'。问题是,我想让拖动的项目只添加到列表 'B' 中的开始和结束项目之间。 see image
这是我目前尝试过的方法:
HTML:
<mat-drawer-container class="example-container">
<mat-drawer mode="side" opened>
<h3>Create your Workflow</h3>
<h5>Drag and drop the elements to visualize the process.</h5>
<div cdkDropList
#optionsList="cdkDropList"
[cdkDropListData]="options"
[cdkDropListConnectedTo]="[workflowList]"
class="example-list"
cdkDropListSortingDisabled
(cdkDropListDropped)="drop($event)"
[cdkDropListEnterPredicate]="noReturnPredicate">
<div class="example-box" cdkDrag *ngFor="let item of options"> {{item}} </div>
</div>
</mat-drawer>
<mat-drawer-content>
<div cdkDropList
#workflowList="cdkDropList"
[cdkDropListData]="workflow"
[cdkDropListConnectedTo]="[optionsList]"
class="example-list"
(cdkDropListDropped)="drop($event)"
[cdkDropListSortPredicate]="sortPredicate"
>
<div class="example-box" [cdkDragDisabled]="item.disabled" *ngFor="let item of workflow" cdkDragLockAxis="y" cdkDrag>{{item.value}}</div>
</div>
</mat-drawer-content>
.ts -> 导出 class:
options = [
'Step',
'Branch'
];
workflow=[
{value: 'Start', disabled: true},
{value: 'Finish', disabled: true}
];
drop(event: any) {
if (event.previousContainer === event.container) {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
} else {
copyArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
}
}
noReturnPredicate(){
return false;
}
sortPredicate(){
return false;
}
现在我只能在工作流程中输入'End'之后的选项。我希望它在开始和结束之间。有人可以帮忙吗?
另外,添加的列表中没有显示选项名称,如果有人能在这方面指导我,那将非常有帮助。谢谢
我在 drop 方法中使用了如下条件:
event.currentIndex>0 && event.currentIndex<this.workflow.length
有两个问题:
两个下拉列表应具有相同的值类型。你有:
options: string[], workflow: {value: string, disabled: boolean}[],
所以,你应该统一类型(或者写你自己的
copyArrayItem
方法来在类型之间转换):interface DragItem { value: string; disabled: boolean; } ... options: DragItem[] = [ { value: 'Step', disabled: ... }, { value: 'Branch', disabled: ... } ]; workflow: DragItem[] = [ { value: 'Start', disabled: true }, { value: 'Finish', disabled: true } ];
如果你想让索引保持在定义的范围内,检查它:
sortPredicate(index: number, drag: CdkDrag, drop: CdkDropList): boolean { // preliminary check, not reliable return index > 0 && index < drop.getSortedItems().length; }
sortPredicate
实际上是不可靠的(我可以将项目放置在禁止位置),你应该仔细检查 drop 事件中的索引行为并修复它:drop(event: CdkDragDrop<DragItem[], any>) { if (event.previousContainer === event.container) { moveItemInArray( event.container.data, event.previousIndex, event.currentIndex ); } else { let currentIndex = event.currentIndex; // double check index range if (0 === currentIndex) { currentIndex++; } if (event.container.getSortedItems().length === currentIndex) { currentIndex--; } copyArrayItem( event.previousContainer.data, event.container.data, event.previousIndex, currentIndex ); } }