Angular 拖放过滤器

Angular Drag and drop with filter

我有一个 Angular 应用程序。其中包含两个工作正常的拖放列表。我想添加一个过滤器来搜索列表中的项目。 问题是当我过滤项目时,函数 transferArrayItem 将使用错误的索引,这就是为什么它会移动错误的项目。
我添加了一个 stackblitz 代码来显示问题。 要重现问题,请按照以下步骤操作:

  1. 在第一个列表中点击搜索并输入数字 2
  2. 尝试将项目移动到第二个列表,它将移动项目 1。

https://stackblitz.com/edit/angular-mwnmo5?file=src%2Fapp%2Fapp.component.ts

https://stackblitz.com/edit/angular-zscthy?file=src%2Fapp%2Fapp.component.ts

您需要在将项目从容器拖放到另一个容器后更新原始 a/b 对象。 所以不可能使用搜索框组件来这样做。

app.component.html,我添加了<input>并删除了<app-search-box>,添加了id到<div cdkDropList>

<input
  #search_a
  type="text"
  class="form-control"
  placeholder="Search"
  aria-label="Search"
  aria-describedby="basic-addon1"
/>

<div
  cdkDropList
  [cdkDropListData]="selectedList"
  class="example-list"
  (cdkDropListDropped)="dropItem($event)"
  id="a_drop_list"
>

app.component.ts,我添加了代码来监听输入按键事件

fromEvent(this.search_a.nativeElement, 'keydown')
  .pipe(
    debounceTime(550),
    map(x => x['target']['value'])
  )
  .subscribe(value => {
    this.updateFilter_a(value);
  })

新增updateFilter函数,输入keydown时触发

  updateFilter_a(val: any) {
    this.selectedList = [];
    this.selectedList = a.filter(v => v.title.indexOf(val)>= 0 || v.description.indexOf(val) >= 0);
  }

修改 dropItem(添加代码以在用户将项目从容器移动到另一个容器时删除 a/b 对象中的项目)

  dropItem(event: CdkDragDrop<any[]>) {
    if (event.previousContainer !== event.container) {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );

  //dropped item id
  const delete_id = event.container.data[event.currentIndex].id;

  //item drop to a_drop_list
  if(event.container.id === 'a_drop_list') {
    //find object b item index when id == device_id
    var index = b.findIndex(function(o){
      return o.id === delete_id;
    })
    //delete item match id == device_id in obejct b
    if (index !== -1) b.splice(index, 1);
  } else if(event.container.id === 'b_drop_list') {
    var index = a.findIndex(function(o){
      return o.id === delete_id;
    })
    if (index !== -1) a.splice(index, 1);
  }
}

我终于找到了用最简洁的代码解决问题的方法。 我使用 id 和 cdkDropList 来了解源列表,然后我手动传输项目而不是使用 cdkDragDrop.

提供的 transferArrayItem 函数

完整代码在
https://stackblitz.com/edit/angular-htpgvx?file=src%2Fapp%2Fapp.component.ts