【问题标题】:Angular Drag and drop with filter带过滤器的角度拖放
【发布时间】:2021-10-26 07:33:11
【问题描述】:

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

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

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

【问题讨论】:

标签: angular angular-material drag-and-drop


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    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,我添加了监听输入keydown事件的代码

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

    【讨论】:

    • 我没有完全理解这些变化。但是,它仍然无法正常工作,但现在出现了不同的问题。尝试在第一个搜索框中输入第一名并将其删除。项目编号 1 将消失且不再显示
    • @Sarahbe 我编辑并修复了问题
    • 这仍然不起作用。它仍然有一些错误。
    • @Sarahbe 你遇到了什么错误?
    • 在第一个搜索框中,键入 2。然后将任何项目从第二个列表移动到第一个列表。现在删除过滤器,您移动的项目将不会出现在任何列表中。无论如何,谢谢你的帮助。请参阅我建议的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 2020-06-26
    • 2017-11-23
    相关资源
    最近更新 更多