以角度限制两个不可拖动项目之间的拖放



我正在制作一个有两个列表的angular应用程序。从列表"A",我可以一次又一次地将项复制到列表"B"。问题是,我想让拖动的项目只添加在列表"B"中的开始和结束项目之间。参见图像

这就是我迄今为止所尝试的:

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->导出类别:

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;
}

现在,我只能在工作流中输入"结束"之后的选项。我希望它在开始和结束之间。有人能帮忙吗?

此外,选项名称没有显示在添加的列表中,如果有人能在这方面指导我,那将非常有帮助。感谢

有两个问题:

  1. 两个下拉列表的值类型应该相同。你有:

    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 }
    ];
    
  2. 如果您想将索引保持在定义的范围内,请检查它:

    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
    );
    }
    }
    

工作示例:https://stackblitz.com/edit/angular-drag-drop-range

我在drop方法中使用了条件,如下所示:

event.currentIndex>0 && event.currentIndex<this.workflow.length

最新更新