igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
77 lines (67 loc) • 3.15 kB
text/typescript
import { HierarchicalTransaction, HierarchicalState, TransactionType } from './transaction';
import { IgxTransactionService } from './igx-transaction';
import { DataUtil } from '../../data-operations/data-util';
import { HierarchicalTransactionService } from './hierarchical-transaction';
/** @experimental @hidden */
export class IgxHierarchicalTransactionService<T extends HierarchicalTransaction, S extends HierarchicalState>
extends IgxTransactionService<T, S> implements HierarchicalTransactionService<T, S> {
public override getAggregatedChanges(mergeChanges: boolean): T[] {
const result: T[] = [];
this._states.forEach((state: S, key: any) => {
const value = mergeChanges ? this.mergeValues(state.recordRef, state.value) : this.cloneStrategy.clone(state.value);
this.clearArraysFromObject(value);
result.push({ id: key, path: state.path, newValue: value, type: state.type } as T);
});
return result;
}
public override commit(data: any[], primaryKeyOrId?: any, childDataKey?: any, id?: any): void {
if (childDataKey !== undefined) {
let transactions = this.getAggregatedChanges(true);
if (id !== undefined) {
transactions = transactions.filter(t => t.id === id);
}
DataUtil.mergeHierarchicalTransactions(data, transactions, childDataKey, primaryKeyOrId, this.cloneStrategy, true);
this.clear(id);
} else {
super.commit(data, primaryKeyOrId);
}
}
protected override updateState(states: Map<any, S>, transaction: T, recordRef?: any): void {
super.updateState(states, transaction, recordRef);
// if transaction has no path, e.g. flat data source, get out
if (!transaction.path) {
return;
}
const currentState = states.get(transaction.id);
if (currentState) {
currentState.path = transaction.path;
}
// if transaction has path, Hierarchical data source, and it is DELETE
// type transaction for all child rows remove ADD states and update
// transaction type and value of UPDATE states
if (transaction.type === TransactionType.DELETE) {
states.forEach((v: S, k: any) => {
if (v.path && v.path.indexOf(transaction.id) !== -1) {
switch (v.type) {
case TransactionType.ADD:
states.delete(k);
break;
case TransactionType.UPDATE:
states.get(k).type = TransactionType.DELETE;
states.get(k).value = null;
}
}
});
}
}
// TODO: remove this method. Force cloning to strip child arrays when needed instead
private clearArraysFromObject(obj: any) {
if (obj) {
for (const prop of Object.keys(obj)) {
if (Array.isArray(obj[prop])) {
delete obj[prop];
}
}
}
}
}