【问题标题】:Angular Drag and Drop absolute position elements selecting wrong index选择错误索引的角度拖放绝对位置元素
【发布时间】:2020-05-04 16:03:44
【问题描述】:

我正在尝试将项目拖到两个列表中。底部列表是典型的排序列表(如“库存”),但我希望顶部项目未排序且可放置在任何地方(如“游戏板”)。

我让它大部分工作,但是当放入顶部框时 event.currentIndex 始终为 0。但是当从那里拖出时,我得到不同的 event.previousIndex 值,这意味着模型和 DOM 元素并不总是匹配。

这是一个stackblitz,说明了我的意思。将一些项目拖到顶部框中并使用它,您会注意到有时移动了错误的项目。

当您以相反的顺序进行交互时最为显着,例如:

  1. 将项目“一”、“二”、“三”拖到顶部框中(按顺序)
  2. 尝试将项目“三”、“二”、“一”放回底框(按此顺序)

【问题讨论】:

    标签: angular angular-cdk-drag-drop


    【解决方案1】:

    cdkDropListSortingDisabled 选项仅在在同一容器中移动项目时有效。如果你从一个容器移动到另一个容器,那么 Angular sorts 块的位置:

    this._itemPositions = this._activeDraggables.map(drag => {
      const elementToMeasure = drag.getVisibleElement();
      return {drag, offset: 0, clientRect: getMutableClientRect(elementToMeasure)};
    }).sort((a, b) => {
      return isHorizontal ? a.clientRect.left - b.clientRect.left :
                            a.clientRect.top - b.clientRect.top;
    });
    

    由于您没有提供方向并且默认为垂直,因此它按top 位置排序。

    顶部框event.currentIndex 始终为 0,因为您使用绝对定位且占位符始终位于顶部。

    尝试添加以下样式以查看占位符的显示位置:

    .cdk-drag-placeholder {
      opacity: 1;
      background: red;
    }
    

    要修复它,您可以自己计算currentIndex,例如像这样:

    const isWithinSameContainer = event.previousContainer === event.container;

    let toIndex = event.currentIndex;
    if (event.container.sortingDisabled) {
      const arr = event.container.data.sort((a, b) => a.top - b.top);
      const targetIndex = arr.findIndex(item => item.top > top);
    
      toIndex =
        targetIndex === -1
          ? isWithinSameContainer
            ? arr.length - 1
            : arr.length
          : targetIndex;
    }
    
    const item = event.previousContainer.data[event.previousIndex];
    item.top = top;
    item.left = left;
    
    if (isWithinSameContainer) {
      moveItemInArray(event.container.data, event.previousIndex, toIndex);
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        toIndex
      );
    }
    

    Forked Stackblitz

    【讨论】:

    • 即使不拖动两个列表,问题仍然存在。在您的分叉版本中,添加所有三个项目,然后在该组中移动它们。你会时不时地注意到一个片段会因为错误的索引而跳跃。 (非常感谢您的帮助)
    • 我忘了检查同一组。你能再测试一下吗? stackblitz.com/edit/two-drop-list-problem-zp556d?file=src/app/…
    • 天啊,你解决了!这几天一直在敲我的头,tysm!
    • 在相同高度(即顶部)有 2 个不重叠元素的情况下如何工作?似乎应该有一个二级排序......
    • 如果你愿意,你也可以应用这个二级排序github.com/angular/components/blob/…
    猜你喜欢
    • 2020-07-18
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多