How to implement drag and drop in Angular2 with a firebase list / FirebaseListObservable

大城市里の小女人 提交于 2019-12-25 09:17:38

问题


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:

  1. You have to get a reference to the element that will be dragged
  2. 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');
    
  3. You combine the Observables so that when a new mousedown on the draggedElement emits, you take all mousemove events, until mouseup is fired.

    let dragAndDrop = down.flatMap(() => move.takeUntil(up));
    
  4. You subscribe to the dragAndDrop Observable and voila

    dragAndDrop.subscribe(position => console.log(position));
    



回答2:


So here are the implementation details:

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!