Angular Data Grid Custom Editing Service
The Angular Grid provides built-in editing directives that handle data operations automatically. However, for complex scenarios where you need more control over the CRUD operations, data validation, or integration with external APIs, you can implement a custom editing service.
Each editing directive exposes an editService property that allows you to replace the default data handling with your own custom logic. The custom service manages the create, read, update, and delete operations and must implement the EditService interface.
If the Grid is not bound to a plain array, you must specify an
EditService.
The following example demonstrates how to implement a custom editing service that batches multiple changes and allows the user to submit them simultaneously with manual save/cancel functionality.
Setup
To implement a custom editing service for the Grid:
-
Create a service that implements the
EditServiceinterface and extendsBehaviorSubjectto manage editing operations and track data changes.typescript@Injectable() export class MyEditService extends BehaviorSubject<Product[]> implements EditService { private data: Product[] = []; private originalData: Product[] = []; private createdItems: Product[] = []; private updatedItems: Product[] = []; private deletedItems: Product[] = []; constructor(private http: HttpClient) { super([]); } }The service extends
BehaviorSubjectto provide reactive data updates that automatically notify the Grid when data changes. The separate arrays track different types of changes, enabling further batch processing where all changes can be submitted together. -
Implement the required CRUD methods of the
EditServiceinterface. The Grid will call these methods when users perform the corresponding editing operations.tspublic create(item: Product): void { // Track new items for batch processing and add them to the data in the UI. this.createdItems.push(item); this.data.unshift(item); // Notify Grid of data change. super.next(this.data); } -
Implement the remaining method required by the
EditServiceinterface, and add custom helper methods for managing the editing state.typescript// Required by EditService interface. public assignValues(target: unknown, source: unknown): void { Object.assign(target, source); } // Custom helper methods for the implementation. public isNew(item: Product): boolean { return !item.ProductID; } public hasChanges(): boolean { return Boolean(this.deletedItems.length || this.updatedItems.length || this.createdItems.length); }The
assignValuesmethod is used by the Grid to update item values during editing operations. -
Create a method that handles submitting all pending changes to the server, and another method for discarding all changes and reverting to the original state.
tspublic saveChanges(): void { if (!this.hasChanges()) { return; } const completed = []; if (this.deletedItems.length) { completed.push(this.fetch(REMOVE_ACTION, this.deletedItems)); } if (this.updatedItems.length) { completed.push(this.fetch(UPDATE_ACTION, this.updatedItems)); } if (this.createdItems.length) { completed.push(this.fetch(CREATE_ACTION, this.createdItems)); } // Clear tracking arrays. this.reset(); // Wait for all operations to complete, then refresh data. zip(...completed).subscribe(() => this.read()); }The
saveChangesmethod groups all pending changes by type and submits them as coordinated server requests using RxJSzipto wait for all operations to complete. This approach provides better error handling and transaction-like behavior. -
Configure the Grid to use your custom service by setting the
editServiceproperty of the Grid and providing the service in your component.typescript@Component({ providers: [MyEditService], template: ` <kendo-grid [kendoGridInCellEditing]="createFormGroup" [editService]="editService" ... > </kendo-grid> ` }) export class AppComponent { constructor(public editService: MyEditService) {} } -
Include custom action buttons in the Grid's toolbar, which will allow users to manually control when changes are collectively submitted or discarded, providing full control over the batch operations.
HTML<ng-template kendoGridToolbarTemplate> <button kendoGridAddCommand>Add new</button> <button kendoButton [disabled]="!editService.hasChanges()" (click)="saveChanges(grid)"> Save Changes </button> <button kendoButton [disabled]="!editService.hasChanges()" (click)="cancelChanges(grid)"> Cancel Changes </button> </ng-template>