用于 Angular 行重新排序的 Kendo Grid - Angular 4/5 - HTML5 拖放 API
Posted
技术标签:
【中文标题】用于 Angular 行重新排序的 Kendo Grid - Angular 4/5 - HTML5 拖放 API【英文标题】:Kendo Grid for Angular Row Reordering - Angular 4/5 - HTML5 Drag and Drop API 【发布时间】:2018-06-15 19:41:58 【问题描述】:我正在尝试实现具有行重新排序功能的 Kendo-Grid,如广告 here 所述。
当 Grid 处理通过 Ajax 调用获取的数据时,行的重新排序(即拖放一行)在视图更改之前不起作用(例如:直到用户单击第二页在这个例子的分页中)
下面是我的 app.component.ts 文件
import State, process from '@progress/kendo-data-query';
import Component, Renderer2, NgZone, AfterViewInit, OnInit, EventEmitter, OnDestroy from '@angular/core';
import Observable from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import Subscription from 'rxjs/Subscription';
import HttpClient, HttpParams from '@angular/common/http';
@Component(
selector: 'my-app',
template: `
<kendo-grid
[data]="gridData"
[height]="410"
[pageable]="true"
[skip]="state.skip"
[pageSize]="state.take"
(dataStateChange)="dataStateChange($event)">
<kendo-grid-column field="id" title="ID" >
</kendo-grid-column>
<kendo-grid-column field="title" title="To Do">
</kendo-grid-column>
<kendo-grid-column field="completed" title="Completed" >
<ng-template kendoGridCellTemplate let-dataItem>
<input type="checkbox" [checked]="dataItem.completed" disabled/>
</ng-template>
</kendo-grid-column>
</kendo-grid>
`
)
export class AppComponent implements OnInit, AfterViewInit, OnDestroy
userData: any[] = []
public state: State =
skip: 0,
take: 10
;
public gridData: any = process(this.userData, this.state);
private currentSubscription: Subscription;
constructor(private renderer: Renderer2, private zone: NgZone, private _http: HttpClient)
ngOnInit()
this.getUserData();
public ngAfterViewInit(): void
this.currentSubscription = this.handleDragAndDrop();
public ngOnDestroy(): void
this.currentSubscription.unsubscribe();
public dataStateChange(state: State): void
this.state = state;
this.gridData = process(this.userData, this.state);
this.currentSubscription.unsubscribe();
this.zone.onStable
.take(1)
.subscribe(() => this.currentSubscription = this.handleDragAndDrop());
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;
));
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(() =>
this.gridData.data.splice(dropIndex, 0, dataItem)
);
));
);
return sub;
getUserData()
return this._http.get('https://jsonplaceholder.typicode.com/todos')
.subscribe((fetchedData) =>
this.userData = fetchedData;
console.log(this.userData);
this.gridData = process(this.userData, this.state);
this.currentSubscription.unsubscribe();
this.currentSubscription = this.handleDragAndDrop();
);
下面是app.module.ts文件
import NgModule from '@angular/core';
import BrowserModule from '@angular/platform-browser';
import BrowserAnimationsModule from '@angular/platform-browser/animations';
import FormsModule from '@angular/forms';
import GridModule from '@progress/kendo-angular-grid';
import HttpClientModule from '@angular/common/http';
import AppComponent from './app.component';
@NgModule(
imports: [ BrowserModule, BrowserAnimationsModule, GridModule, FormsModule, HttpClientModule],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
)
export class AppModule
Plunker Here.
注意:我曾尝试在我的 Ajax 数据调用中重新订阅 handleDragAndDropevent,但这也不起作用。
提前致谢!
【问题讨论】:
telerik.com/kendo-angular-ui/components/knowledge-base/… 【参考方案1】:关键是您仅在通过AppComponent.dataStateChange()
调用更改state
时才调用AppComponent.handleDragAndDrop()
。它发生在网格页面更改时,不会发生在数据初始化时。因此,快速修复将是
getUserData()
return this._http.get('https://jsonplaceholder.typicode.com/todos')
.subscribe((fetchedData) =>
this.userData = fetchedData;
console.log(this.userData);
this.dataStateChange(this.state); // force state change, encapsulate process() call
);
固定 Plunker 是 here。
【讨论】:
以上是关于用于 Angular 行重新排序的 Kendo Grid - Angular 4/5 - HTML5 拖放 API的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Kendo Grid + Angular 4 中以编程方式设置选定行?
SSE 优化(行重新排序、操作整理)中的编译器(例如 g++)有多聪明