【问题标题】:Angular Material Drag & Drop : Custom Pipe Issue角材料拖放:自定义管道问题
【发布时间】:2020-01-09 03:16:59
【问题描述】:

我正在开发一些使用 Angular Material Drag And Drop 的项目。 我在 StackBlitz 上做了一个简化的例子 https://stackblitz.com/edit/drag-and-drop-with-pipe?file=src%2Fapp%2Fdispatch.component.ts

宠物清单和箱子清单。 您可以将宠物拖放到盒子列表的区域中,这样每个盒子都可以包含 X 只宠物。

这行得通! 但我想添加一个自定义管道来动态过滤每个列表,例如只显示猫或名为 Rex 的宠物

我对 Angular 和 JS/TS 还很陌生,我找到了这段代码来制作我的自定义管道

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'listFilter'
})
export class ListFilterPipe implements PipeTransform {

  transform(items: any[], searchText: string): any[] {
    if (!items) return [];
    if (!searchText) return items;

    return items.filter(item => {
      return Object.keys(item).some(key => {
        return String(item[key]).toLowerCase().includes(searchText.toLowerCase());
      });
    });
   }

}

我还使用 Material 文档中给出的拖放事件示例

drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      transferArrayItem(event.previousContainer.data,
                        event.container.data,
                        event.previousIndex,
                        event.currentIndex);
    }
  }


这行得通! 但是没有!

没有过滤器,当宠物被放入盒子时,它会从宠物列表中消失并出现在盒子中。没关系!

但是使用过滤器(例如,名称 = 索引为 1 的雷克斯),当我拖放宠物时,将错误的放在框中(实际上是“斯特拉”,索引为 0 但被隐藏)并且雷克斯仍然出现在宠物列表中。

我希望我的解释清楚(对不起我的英语),但你可以在上面提到的这个 stackblitz 上尝试一下:如果你过滤宠物并进行拖放,错误的宠物会被移动。

这个 gif 说明了这个问题:

似乎 drop 事件采用了未过滤列表的索引,我不知道如何修复它。

非常感谢。

【问题讨论】:

  • 你解决过这个问题吗?
  • 是的。我不得不使用一种解决方法。我放弃了管道解决方案以实现自制过滤功能。我现在使用 2 个列表,一个“原始”列表和一个带有 arry.filter() 的过滤副本。现在显示过滤后的列表,不适合过滤器的每个项目都不会隐藏,而是不存在,因此索引是正确的并且在每次拖放时,“原始”列表都会更新。有点脏,但对我来说已经足够了

标签: javascript angular typescript angular-material


【解决方案1】:

您好,我遇到了同样的问题并进行了大量研究,我已经实现了这一点,在这种情况下,可以在该卡上使用 touchend 事件和 mousedown 事件并传递当前项和数组

以下代码用于手机触摸屏 touchend

<div*ngFor="let item of array">
<div (touchend)="dragTouchEndEvent(array,item)">
</div>
</div>

此代码用于桌面浏览器 (mousedown)

<div*ngFor="let item of array">
    <div (mousedown)="dragTouchEndEvent(array,item)">
    </div>
    </div>

声明一个变量

 previousIndex:number;

所以在该组件的 ts 文件中添加这个

 dragTouchEndEvent(itemArray, item) {
    this.previousIndex = itemArray.findIndex(e => e === item);
  }

现在将 event.previousIndex 替换为 this.previousIndex 并清除您的搜索过滤器

 someMethod(event: CdkDragDrop<any>){
        if (event.previousContainer === event.container) {
              moveItemInArray(event.container.data, this.previousIndex, event.currentIndex);
            } else {
              transferArrayItem(event.previousContainer.data,
                event.container.data,
                this.previousIndex,
                event.currentIndex);
    
            }
//clear your search filter here
}

【讨论】:

    猜你喜欢
    • 2015-11-13
    • 2021-04-05
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 2019-11-22
    • 1970-01-01
    相关资源
    最近更新 更多