问题
I am trying to implement drag and drop into a list using angular2, firebase and dragula. I'm not tied to using dragula if there is a better module already built, but it seems simple. So far I get errors because dragula is trying to reorder the list as if it were a normal array.
<ul class="list-group" [dragula]="statusList" [dragulaModel]='statusService.$statuses'>
<li *ngFor="let status of statusService.$statuses | async" class="list-group-item">
<span class="handle">
<img src="../../images/handle.png" />
</span>
<span class="swatch" [style.backgroundColor]="status.color"></span>
<span class="title">
<inline-editor type="text" [(ngModel)]="status.title" (keyup.enter)="updateStatus(status, status.title)" (onSave)="updateStatus(status, status.title)" name="title" ngDefaultControl></inline-editor>
</span>
<a (click)="statusService.removeStatus(status)" class="remove-status">
<i class="fa fa-times"></i>
</a>
</li>
</ul>
I have implemented drag and drop with firebase and angular using the priority property. I am not seeing a clear way to do it in Angular 2, however.
回答1:
Observables are a perfect fit for creating drag-and-drop events.
Basically, this boils down to this:
- You have to get a reference to the element that will be dragged
You have to create 3 different Observables:
let down = Observable.fromEvent(draggedElement, 'mousedown'); let move = Observable.fromEvent(document, 'mousemove'); let up = Observable.fromEvent(document, 'mouseup');
You combine the Observables so that when a new
mousedown
on thedraggedElement
emits, you take allmousemove
events, untilmouseup
is fired.let dragAndDrop = down.flatMap(() => move.takeUntil(up));
You subscribe to the dragAndDrop Observable and voila
dragAndDrop.subscribe(position => console.log(position));
回答2:
So here are the implementation details:
- I used Alexander's advice to subscribe to the firebase list and create a local array:
this.statusService.$statuses.subscribe((statuses: [IStatus]) => {
this.statuses = []; //reset local array used with dragula for drag and drop
for (let status of statuses) {
this.statuses.push(status);
}
})
- I used dragula's drop event to loop through and update the priority for each item in the array:
dragulaService.drop.subscribe(() => {
this.statuses.forEach((status, index) => {
this.statusService.$statuses.update(status.$key, {
priority: index
});
})
});
- I ordered by priority in the query:
this.$statuses = this.af.database.list(`/statuses/${session.$key}`, {
query: {
orderByChild: 'priority'
}
});
Finally I just use the local array as the dragula model and for *ngFor:
<ul class="list-group" [dragula]="statusList" [dragulaModel]='statuses'>
<li *ngFor="let status of statuses" class="list-group-item">
etc...
来源:https://stackoverflow.com/questions/40049734/how-to-implement-drag-and-drop-in-angular2-with-a-firebase-list-firebaselistob