Kendo Sortable for Angular - 获取新的索引位置

Posted

技术标签:

【中文标题】Kendo Sortable for Angular - 获取新的索引位置【英文标题】:Kendo Sortable for Angular - Getting the new index position 【发布时间】:2018-04-07 16:10:45 【问题描述】:

使用的框架

Angular 和 Kendo 用户界面

我在做什么

我有一个通过 Firestore 获得的数据列表

已根据 firestore 中的属性订购

我已安装 Kendo Sortable 并将其导入到我的模块中

工作原理

我可以拖动项目 UI

什么不起作用

根据文档,我正在写入控制台以查看项目的索引

onDragStart() 的索引位置似乎是正确的

onDragEnd() 始终显示为 -1(见附件截图) console log of dragging items about

问题

    我的目标是移动列表项并获取它们的新索引项。希望从那里我可以编写一个函数来将新位置写回数据库。但是,有没有办法确定正确的“结束”索引?

Component.ts

import  Component, OnInit, ViewEncapsulation  from '@angular/core';
import  Observable  from 'rxjs/Observable';
import  AngularFirestore, AngularFirestoreCollection  from 'angularfire2/firestore';
import  Router, ActivatedRoute  from '@angular/router';
import  DataEvent, DragDropEvent  from '@progress/kendo-angular-sortable';

@Component(
  selector: 'app-albums-list',
  templateUrl: './albums-list.component.html',
  styleUrls: ['./albums-list.component.css'],
  encapsulation: ViewEncapsulation.None // testing
)

export class IssuesListComponent implements OnInit 

  private albumsCollection: AngularFirestoreCollection<any>;
  albums: Observable<any[]>;
  albumFolderId: string;


 //  KENDO TESTING

public events: string[][] = [[], []];

public onDataAdd(src: number, e: DataEvent): void 
  console.log(src, 'dataAdd', e.index);


public onDataRemove(src: number, e: DataEvent): void 
  console.log(src, 'dataRemove', e.index);


public onDragEnd(src: number, e: DragDropEvent): void 
  console.log(src, 'dragEnd', e.index);


public onDragOver(src: number, e: DragDropEvent): void 
  // Not logging due to the large number of events


public onDragStart(src: number, e: DragDropEvent): void 
  console.log(src, 'dragStart', e.index);


// private log(src: number, event: string, itemIndex: number): void 
//   this.events[src].push(`$event - $this.items[src][itemIndex]`);
// 

  constructor(
    private readonly afs: AngularFirestore,
    private activatedRoute: ActivatedRoute,
    private router: Router
  )  


  ngOnInit() 

    // Look at the url for the Folder ID and set the local variable
    this.activatedRoute.params.forEach((urlParameters) => 
      this.albumFolderId = urlParameters['folderId'];

      // Return the issues list
      this.getAlbumData();

    );


  


  getAlbumData() 

    this.albumCollection = this.afs.collection<any>(`/albumFolders/$this.albumFolderId/albums`, ref => 
      return ref.orderBy('album_order');
    );

    // Get the data
    this.albums = this.albumCollection.snapshotChanges().map(actions => 

      return actions.map(a => 

        const data = a.payload.doc.data();

        const id = a.payload.doc.id;

        return  id, ...data ;

      );
    );
  

Component.html

 <kendo-sortable
            [navigatable]="true"
            [animation] = "true"
            [data]="albums | async"
            class="list__ul"
            itemClass="list__li"
            activeItemClass=""
            (dataAdd)="onDataAdd(i, $event)"
            (dataRemove)="onDataRemove(i, $event)"
            (dragEnd)="onDragEnd(i, $event)"
            (dragOver)="onDragOver(i, $event)"
            (dragStart)="onDragStart(i, $event)"
            >

            <ng-template let-item="item">         
                <h2 class="list__h2">  item.album_title  </h2>
                <span class="list__sub">  item.album_date </span>
            </ng-template>

        </kendo-sortable>

【问题讨论】:

【参考方案1】:

如果我具体理解 ti,你想要掺杂文件的索引吗?

在这个 Kendo Angular 2 示例中,您可以看到您想要的索引(我添加了控制台日志以显示索引在哪里):

 private handleDragAndDrop(): Subscription 
    const sub = new Subscription(() => );
    let draggedItemIndex;

    document.querySelectorAll('.k-grid-content tr')
    .forEach(item => 
        this.renderer.setAttribute(item, 'draggable', true);
        const dragStart = Observable.fromEvent(item, 'dragstart');
        const dragOver = Observable.fromEvent(item, 'dragover');
        const drop = Observable.fromEvent(item, 'drop');

        sub.add(dragStart.subscribe((target) => 
            draggedItemIndex = target.rowIndex;
            console.log("Drag start: " + target.rowIndex)
        ));

        sub.add(dragOver.subscribe((e: any) => e.preventDefault()));

        sub.add(drop.subscribe((e: any) => 
            e.preventDefault();
            const dataItem = this.gridData.data.splice(draggedItemIndex, 1)[0];
            const dropIndex = e.target.closest('tr').rowIndex;
            this.zone.run(() =>
                console.log("Drag drop/stop: " + dropIndex)
                this.gridData.data.splice(dropIndex, 0, dataItem)
            

            );
        ));
    );

http://plnkr.co/edit/gUGZM5yOG4v2CwvsjEV6?p=preview

【讨论】:

【参考方案2】:

我通过使用局部变量元素引用(例如#element)来做到这一点。通过将此作为参数传递给dragEnd 事件,可以确定新订单。

组件 HTML

<kendo-sortable #sortable [data]="stages" (dragEnd)="onDragEnd(sortable.data)">
    <ng-template let-stage="item">
        <div draggable="true">stage.name</div>
    </ng-template>
</kendo-sortable>

组件 .ts 中的 onDragEnd 处理程序

public onDragEnd(data): void 
    let newOrder = data.map(o=>o.id);

【讨论】:

以上是关于Kendo Sortable for Angular - 获取新的索引位置的主要内容,如果未能解决你的问题,请参考以下文章

封装扩展Kendo UI Grid

在 Kendo 网格中绑定事件

以 Kendo Grid 页面大小显示全部

将对象拖入可排序列表 - AngularJS

Kendo UI 网格 URL 列

Kendo MVVM Grid - 如何响应行点击事件?