I have written a custom Kendo Grid databinding directive that allows me to pass in a service method to be called by rebind()
. Effectively, the component using the Kendo grid is responsible for passing the method to the directive:
<kendo-grid
[customDataBinding]="myData"
[queryFn]="requeryGrid()">
Inside the component, the requeryGrid()
function looks like this:
requeryGrid(): QueryFn {
// have to bind reportService because reportService depends on a separate data service
return this.rportService.cmmcLevel2SelfSearch.bind(this.reportService);
}
The directive rebind()
method itself is defined as:
override rebind(): void {
//this.grid.loading = true;
this.queryFn(this.state)
.pipe(
take(1),
map((queryResult) => {
const total : number = queryResult ? queryResult.length : 0;
const result: GridDataResult = {
data: queryResult,
total: total
};
return result;
}),
tap((queryResult) => {
this.grid.data = queryResult;
//this.grid.loading = false;
this.notifyDataChange();
}),
catchError((error) => {
//this.grid.loading = false;
return throwError(() => error);
})
)
.subscribe();
}
According to the Chrome developer console, the queryFn is executed against the backend API, and returns the results I want. Unfortunately, even when setting the grid data and calling notifyDataChange()
the grid does not update.
I assume this is something simple I'm overlooking. Can anyone see this issue?
Since you are directly updating the data
property internal to the kendo-grid
, the ngOnChanages
is not fired. Just trigger this.cdr.detectChanges()
after setting data
.
private cdr = inject(ChangeDetectorRef); // <- changed here!
...
...
override rebind(): void {
//this.grid.loading = true;
this.queryFn(this.state)
.pipe(
take(1),
map((queryResult) => {
const total : number = queryResult ? queryResult.length : 0;
const result: GridDataResult = {
data: queryResult,
total: total
};
return result;
}),
tap((queryResult) => {
this.grid.data = queryResult;
//this.grid.loading = false;
this.notifyDataChange();
this.cdr.detectChanges(); // <- changed here!
}),
catchError((error) => {
//this.grid.loading = false;
return throwError(() => error);
})
)
.subscribe();
}