使用 Observable 作为数据源的 Angular 拖放

标签 angular angular-material angular-cdk-drag-drop

我想使用 Observable 作为 Material 拖放的数据源,但目前我正在苦苦挣扎。基本上我在看板中有一个泳道列表,每个泳道都有一堆我想要移动的项目。当我移动一个项目时,我也想更新后端。多人也会更新同一个看板,所以我也想使用 socket.io 自动移动项目(出于同样的原因,我也在努力解决这个问题)

这是模板:

<button mat-raised-button color="primary" (click)="addItem()">Add Item</button>

<button mat-raised-button color="primary" (click)="moveItem()" style="margin-left:10px">Move Item</button>

<div cdkDropListGroup>
<div class="example-container" *ngFor="let lane of swimlanes">
  <h2>{{lane.name}}</h2>

  <div
    cdkDropList
    #doneList="cdkDropList"
    [cdkDropListData]="lane.array | async"
    class="example-list"
    (cdkDropListDropped)="drop($event)">
    <div class="example-box" *ngFor="let item of lane.array | async" cdkDrag>{{item.name}}</div>
  </div>
</div>

</div>

这是组件代码:
import {Component, OnInit} from '@angular/core';
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
import { Subscription, of, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Swimlane{
  name: string;
  array: Observable<Task[]>;
}

export interface Task{
  name: string;
  list: string;
}

/**
 * @title Drag&Drop connected sorting
 */
@Component({
  selector: 'cdk-drag-drop-connected-sorting-example',
  templateUrl: 'cdk-drag-drop-connected-sorting-example.html',
  styleUrls: ['cdk-drag-drop-connected-sorting-example.css'],
})
export class CdkDragDropConnectedSortingExample implements OnInit {

//These will eventually come from an API.
  items:Task[] = [
    {name: "Get to work", list: "To Do"},
    {name: "Pick up groceries", list: "To Do"},
    {name: "Go home", list: "To Do"},
    {name: "Fall asleep", list: "To Do"},
    {name: "Get up", list: "Done"},
    {name: "Brush teeth", list: "Done"},
    {name: "Take a shower", list: "Done"},
    {name: "Check e-mail", list: "Done"},
    {name: "Walk dog", list: "Done"}
  ];


  swimlanes:Swimlane[] = [];

//Create Observables as the data sources
  itemsObservable:Observable<Task[]>;

  todo:Observable<Task[]>;
  done:Observable<Task[]>;

  ngOnInit(): void {

    this.itemsObservable = of(this.items);

    this.todo = this.itemsObservable.pipe(
       map((item:Task[]) => item.filter((item:Task) => item.list === "Done")
     ));

    this.done = this.itemsObservable.pipe(
       map((item:Task[]) => item.filter((item:Task) => item.list === "To Do")
     ));    

    this.swimlanes.push({name:"To Do", array: this.todo});
    this.swimlanes.push({name:"Done", array: this.done});
  }

addItem(){
  this.items.push({name: "New Item", list: "To Do"});
  console.log(this.items.length);
}

moveItem(){

}

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

Here's a stackblitz我试图使用 observables 作为数据源的地方。您可以看到它正确加载了 channel ,但是当您尝试移动其中一个项目时,它会消失。有任何想法吗?

在我的实际应用程序中,我从 API 请求接收值。所以它会自 Action 为一个 Observable 出现。然后我进入一个本地基本数组并取消订阅 Observable。然后我从本地基数组创建一个新的 Observable 并对本地基数组进行更改,希望更改将反射(reflect)在拖放中。但这目前不起作用。

很高兴编写我自己的移动功能,但是如果没有反射(reflect) Observable 数据源更改的 channel ,我无法让它工作。

最佳答案

我遇到了同样的问题。显然 Angular DnD 不喜欢 cdkDropListData 中的 observables。然而,有一个解决方案。
大体的想法是不使用 observables 作为 droplist 的数据源,而是使用 observables.subscribe 来填充 droplist 的数据源。
所以而不是这个:

this.swimlanes.push({name: "To Do", array: this.todo})
我这样做了:
this.todo.subscribe(data => {
  console.log(data)
  this.swimlanes.push({name: "To Do", array: data})
})
您必须从 subscribe 方法将数据填充到泳道。
我 fork 了你的 stackblitz 并使它起作用。
stackblitz fork
我希望这有帮助。
将新项目添加到待办事项列表:
addItem(){
  this.baseTaskList.subscribe(items => {
    this.swimlanes[0]["array"]
      .push({"task": "New Task", "list":"To Do"})
      })
  }
您将新项目添加到 http 帖子订阅中的 droplist 容器中,假设您还将通过某个 API 将新项目发布到某种数据库中。 post 的响应将是您需要添加到本地容器中的项目的新插入项目的 ID,以便将来进行数据操作,您需要知道行 ID(删除、更新)

关于使用 Observable 作为数据源的 Angular 拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61317451/

相关文章:

javascript - 如何在规范文件中注入(inject)服务 Angular Testing (Jasmine/karma)

angular - 名称为 : 'eventGraphicAttachment' 的表单控件没有值访问器

angular - CdkDropList enter deprecated 在 CdkDropList 中不存在

Angular cdk 拖放 - 动态占位符高度

http - 如何从 angular2 RC5 中的 API 下载 PDF?

Angular 6 防止[隐藏]在页面加载时闪烁

angular - 在 Angular Material 表(mat-table)中混合静态和动态列

contenteditable 不适用于 cdkDrag

html - 模型驱动形式 : validation not working as expected in Angular 2

javascript - Angular Material 垫选择 : values are function with submit button