Angular 使用 Observable 作为数据源拖放
Angular Drag and Drop using Observable as datasource
我想使用 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 我尝试将可观察对象用作数据源的地方。您可以看到它正确加载了通道,但是当您尝试移动其中一个项目时它消失了。有什么想法吗?
在我的实际应用中,我从 API 请求中接收值。所以它自动作为一个 Observable 出现。然后我将其分解为本地基本数组并取消订阅 Observable。然后我从本地基数组创建一个新的 Observable 并对本地基数组进行更改,希望这些更改会反映在拖放中。但这目前不起作用。
很高兴编写我自己的移动功能,但是没有反映对 Observable 数据源的更改的通道,我无法让它工作。
我运行陷入同样的问题。显然 Angular 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})
})
您必须通过订阅方法将数据填充到泳道。
我分叉了你的 stackblitz 并让它工作。
希望对您有所帮助。
正在将新项目添加到待办事项列表中:
addItem(){
this.baseTaskList.subscribe(items => {
this.swimlanes[0]["array"]
.push({"task": "New Task", "list":"To Do"})
})
}
您将在订阅 http post 时将新项目添加到下拉列表容器中,假设您还将 post 通过一些 [=36] 将新项目添加到某种数据库中=]. post 的响应将是新插入项目的 ID,您需要将其添加到本地容器中的项目以供将来需要知道行 ID(删除、更新)的数据操作
我想使用 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 我尝试将可观察对象用作数据源的地方。您可以看到它正确加载了通道,但是当您尝试移动其中一个项目时它消失了。有什么想法吗?
在我的实际应用中,我从 API 请求中接收值。所以它自动作为一个 Observable 出现。然后我将其分解为本地基本数组并取消订阅 Observable。然后我从本地基数组创建一个新的 Observable 并对本地基数组进行更改,希望这些更改会反映在拖放中。但这目前不起作用。
很高兴编写我自己的移动功能,但是没有反映对 Observable 数据源的更改的通道,我无法让它工作。
我运行陷入同样的问题。显然 Angular 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})
})
您必须通过订阅方法将数据填充到泳道。
我分叉了你的 stackblitz 并让它工作。
希望对您有所帮助。
正在将新项目添加到待办事项列表中:
addItem(){
this.baseTaskList.subscribe(items => {
this.swimlanes[0]["array"]
.push({"task": "New Task", "list":"To Do"})
})
}
您将在订阅 http post 时将新项目添加到下拉列表容器中,假设您还将 post 通过一些 [=36] 将新项目添加到某种数据库中=]. post 的响应将是新插入项目的 ID,您需要将其添加到本地容器中的项目以供将来需要知道行 ID(删除、更新)的数据操作