我正在尝试按行广告here实施具有行重新排序功能的Kendo-Grid。
当Grid处理通过Ajax调用获取的数据时,行的重新排序(即拖放行)在视图更改之前不起作用(例如:直到用户单击第2页在这个例子的分页中)
以下是我的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" width="60">
</kendo-grid-column>
<kendo-grid-column field="title" title="To Do">
</kendo-grid-column>
<kendo-grid-column field="completed" title="Completed" width="60">
<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 { }
注意:我已尝试在我的Ajax数据调用中重新订阅handleDragAndDropevent,但这也不起作用。
提前致谢!
答案 0 :(得分:2)
关键是,只有在通过AppComponent.handleDragAndDrop()
电话更改state
时才会呼叫AppComponent.dataStateChange()
。它发生在网格页面更改上,并且不会在数据初始化时发生。所以,快速修复将是
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。