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

Angular 使用Observable作为数据源的角度拖放,angular,angular-material,angular-cdk-drag-drop,Angular,Angular Material,Angular Cdk Drag Drop,我想使用一个可观察的对象作为材料拖放的数据源,但目前我正在努力。基本上,我在看板上有一个泳道列表,每个泳道都有一堆我想移动的项目。当我移动一个项目时,我也想更新后端。多个人也会更新同一看板,所以我想使用socket.io来自动移动这些项目(出于同样的原因,我也在努力) 以下是模板: <button mat-raised-button color="primary" (click)="addItem()">Add Item</button> <button mat-

我想使用一个可观察的对象作为材料拖放的数据源,但目前我正在努力。基本上,我在看板上有一个泳道列表,每个泳道都有一堆我想移动的项目。当我移动一个项目时,我也想更新后端。多个人也会更新同一看板,所以我想使用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>
添加项目
移动项目
{{lane.name}
{{item.name}
以下是组件代码:

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);
    }
  }
}
从'@angular/core'导入{Component,OnInit};
从“@angular/cdk/drag drop”导入{CdkDragDrop,moveItemInArray,transferArrayItem};
从“rxjs”导入{Subscription,of,Observable};
从“rxjs/operators”导入{map};
导出接口泳道{
名称:字符串;
阵列:可观测;
}
导出接口任务{
名称:字符串;
列表:字符串;
}
/**
*@title拖放连接排序
*/
@组成部分({
选择器:“cdk拖放连接排序示例”,
templateUrl:'cdk拖放连接排序示例.html',
styleURL:['cdk-drag-drop-connected-sorting-example.css'],
})
导出类CdkDragDropConnectedSortingExample实现OnInit{
//这些最终将来自API。
项目:任务[]=[
{姓名:“开始工作”,列表:“要做”},
{姓名:“拿起杂货”,列表:“要做”},
{姓名:“回家”,列表:“要做”},
{姓名:“入睡”,列表:“要做”},
{name:“起床”,list:“完成”},
{名称:“刷牙”,列表:“完成”},
{姓名:“洗澡”,列表:“完成”},
{名称:“检查电子邮件”,列表:“完成”},
{名称:“走狗”,列表:“完成”}
];
泳道:泳道[]=[];
//创建可观察对象作为数据源
项目可观察:可观察;
todo:可观察的;
完成:可见;
ngOnInit():void{
this.itemsObservable=of(this.items);
this.todo=this.itemsObservable.pipe(
映射((项:任务[])=>item.filter((项:任务)=>item.list===“完成”)
));
this.done=this.itemsObservable.pipe(
映射((项:任务[])=>item.filter((项:任务)=>item.list===“待办事项”)
));    
this.swimlanes.push({name:“To Do”,数组:this.todo});
this.swimlanes.push({name:“Done”,数组:this.Done});
}
附加项(){
this.items.push({name:“New Item”,list:“To Do”});
console.log(this.items.length);
}
移动项目(){
}
drop(事件:CdkDragDrop){
if(event.previousContainer==event.container){
moveItemInArray(event.container.data、event.previousIndex、event.currentIndex);
}否则{
transferArrayItem(event.previousContainer.data,
event.container.data,
event.previousIndex,
事件(当前索引);
}
}
}
我尝试使用可观测数据作为数据源的地方。您可以看到它正确加载车道,但当您尝试移动其中一个项目时,它会消失。有什么想法吗

在我的实际应用程序中,我从API请求接收值。因此,它会自动以可观察的形式出现。然后我将其分解成一个本地基数组,并取消对可观察对象的订阅。然后,我从本地基数组创建一个新的可观察对象,并对本地基数组进行更改,希望这些更改将反映在拖放中。但这目前不起作用


我很乐意编写自己的移动功能,但是如果没有反映对可观察数据源的更改的车道,我就无法让它工作。

我遇到了同样的问题。显然,角度DnD不喜欢cdkDropListData中的观察值。然而,有一个解决办法

一般的想法是不使用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方法将数据填充到泳道

我完成了你的闪电战并成功了

我希望这有帮助

将新项目添加到待办事项列表:

addItem(){
  this.baseTaskList.subscribe(items => {
    this.swimlanes[0]["array"]
      .push({"task": "New Task", "list":"To Do"})
      })
  }

您将把新项目添加到http post订阅中的droplist容器中,假设您还将通过一些API将新项目发布到某种数据库中。post的响应将是新插入项的ID,您需要将其添加到本地容器中的项中,以便将来进行数据操作,您需要知道行ID(删除、更新)

您尝试过使用异步管道吗?看到了吗?好的,我试着提供最低限度的修改,所以你的建议确实解决了我的打字错误。不过,我已经更新了stackblitz以显示实际问题。我想能够过滤主列表和过滤后的观测值来呈现我的泳道。谢谢你的尝试!您是否成功地在待办事项列表中显示了新项目?通过添加新项目更新了答案。