【问题标题】:Fixed sorting using cdkDrag in Angular2?在 Angular2 中使用 cdkDrag 修复排序?
【发布时间】:2022-02-04 19:00:30
【问题描述】:

我试图阻止在使用 Angular CDK 拖放进行排序期间禁用的移动项目

<div cdkDropList class="example-list" 
[cdkDropListSortPredicate]="sortPredicateForDisableItem(items)"
(cdkDropListDropped)="drop($event)">
<div
  class="example-box"
  *ngFor="let item of items"
  cdkDrag
  [cdkDragDisabled]="item.disabled">{{item.value}}</div>
</div>

在组件中,

public items = [
    {value: 'I can be dragged 1', disabled: false},
    {value: 'I can be dragged 2 ', disabled: false},
    {value: 'I cannot  be dragged and i want to be fixed in position 3', disabled: true},
    {value: 'I can be dragged 4 ', disabled: false,dinesh: 'kumar'},
  ];
sortPredicateForDisableItem(items: any) {
    // This logic fails to prevent moving disabled item
    return function(index: number, item: CdkDrag, drop: CdkDropList){
    return items[index].disabled === false
    }
  }

排序前

排序后,Item3移动到新位置,无法固定位置

DEMO

具有禁用属性的项目可以固定在它所属的位置吗?期望是,禁用的项目在排序期间始终保留在相同的索引/位置。请指教

【问题讨论】:

    标签: javascript angular typescript angular-material angular-cdk-drag-drop


    【解决方案1】:

    您不能简单地将禁用的项目“锁定”到位,因为例如从索引 0 拖动到索引 3 将影响其间所有项目的索引。您要做的实际上是不允许会更改禁用项的索引的拖动操作。

    那么,你需要做的是:

    1. 加载项目并按正确顺序排序。
    2. 更改拖放逻辑以检查是否允许操作
    3. 要么禁止该操作,要么按照您想要的逻辑修改其效果

    我已经分叉了你的 stackblitz here 并准备了一个简单的解决方案。我尚未对其进行彻底测试,但它应该可以让您基本了解它应该如何工作。

    它所做的基本上是在here的原始函数的基础上编写自定义moveItemInArray函数:

      private moveItemInArrayIfAllowed(
        array: any[],
        fromIndex: number,
        toIndex: number
      ): void {
        const from = this.clamp(fromIndex, array.length - 1);
        const to = this.clamp(toIndex, array.length - 1);
    
        if (from === to) {
          return;
        }
    
        const target = array[from];
        const delta = to < from ? -1 : 1;
    
        const affectedItems = array.filter((item, index) =>
          delta > 0 ? index >= from && index <= to : index >= to && index <= from
        );
    
        // If any of the items affected by the index changes is disabled
        // don't move any of the items.
        if (affectedItems.some((i) => i.disabled)) {
          return;
        }
    
        for (let i = from; i !== to; i += delta) {
          array[i] = array[i + delta];
        }
    
        array[to] = target;
      }
    
      private clamp(value: number, max: number): number {
        return Math.max(0, Math.min(max, value));
      }
    

    【讨论】:

    • 感谢您的时间,是的,它在下降后工作。这也可能是解决方案。我试图在 drop 发生之前使用谓词事件
    猜你喜欢
    • 1970-01-01
    • 2014-01-13
    • 2017-09-05
    • 1970-01-01
    • 2014-06-07
    • 2015-02-23
    • 2016-12-12
    • 2020-11-23
    • 1970-01-01
    相关资源
    最近更新 更多