트랜잭션 서비스 클래스 계층
Transaction, State, Transaction Log
The Transaction is the main building block of the Transaction service. The Transaction is actually every operation that you execute on the data. The Transaction interface defines three properties: id, newValue and type.
The id of the Transaction should be unique per data record and defines the record that this transaction is affecting. The type may be any of the three transaction types: ADD, DELETE and UPDATE, depending what operation you execute. The newValue contains the value of the new record in case you are adding an ADD transaction. If you are updating an existing record, the newValue would contain the changes only. You may have several transactions of UPDATE type with same id. If you are deleting a record, the newValue will contain the value of the deleted record.
트랜잭션 서비스 사용 방법 항목에서 각 트랜잭션 유형을 추가하는 방법에 대한 예를 볼 수 있습니다.
Every time you add a Transaction, it is added to the transaction log and undo stack. All the changes in the transaction log are then accumulated per record. From that point, the service maintains an aggregated State. The State consists of unique records and every record may be of one of the supported transaction types, mentioned above.
While adding transactions you may turn on pending transactions by calling startPending. All subsequent transactions will be accumulated in single transaction until you call endPending. If you pass true to endPending all accumulated transactions will be added as a single transaction in the transaction log and in the undo stack.
Using igxBaseTransaction
Our grid module provides a very basic implementation of the Transaction service (igxBaseTransactionService) with just pending session functionality allowing for Row Editing feature. By using startPending and endPending Row editing can combine multiple per-cell operations into a single change. This means editing multiple cells of a single record creates a single transaction and you can handle just the row edit event.
누적된 상태가 부분 개체이므로 서비스를 사용하여 어떤 셀이 편집되었는지 확인하고 해당 셀을 중심으로 UI를 구축할 수도 있습니다.
The igxBaseTransactionService has no undo stack so it does not provide undo/redo functionality.
A detailed example of how you may use igxBaseTransactionService to enable Row Editing is provided in the following topics:
General information on igxTransactionService and igxHierarchicalTransactionService
igxTransactionService and igxHierarchicalTransactionService are injectable middlewares, that implement the Transaction Service interface. A component may use those to accumulate changes without affecting the underlying data. The provider exposes API to access, manipulate (undo and redo) and discard or commit one or all changes to the data.
In a more concrete example, igxTransactionService and igxHierarchicalTransactionService can work with both cell editing and row editing of the IgxGrid. The transaction for the cell edit is added when the cell exits edit mode. When row editing starts the grid sets its transaction service in pending state by calling startPending. Each edited cell is added to the pending transaction log and is not added to the main transaction log. When the row exits edit mode all the changes are added to the main transaction log and to the undo log as a single transaction.
두 경우 모두(셀 편집 및 행 편집) 그리드 편집 상태는 업데이트, 추가 및 삭제된 모든 행과 마지막 상태로 구성됩니다. 나중에 한 번에 또는 ID별로 검사, 조작 및 제출할 수 있습니다. 변경 사항은 편집 모드에 따라 개별 셀이나 행에 대해 수집되고 데이터 행/레코드별로 누적됩니다.
Using igxTransactionService
igxTransactionService extends igxBaseTransactionService.
If you want your component to use transactions when making data operation, you need to define the igxTransactionService as a provider in your component's providers array.
The igxTransactionService provides an undo stack so you may get advantage of the undo/redo functionality. The Undo stack is actually an array that contains arrays of transactions. When using the igxTransactionService, you may check the canUndo accessor in order to understand if there are any transactions in the Undo stack. If there are - you may use the undo method to remove the last transaction and redo to apply the last undone transaction.
다음 주제에서 일괄 편집 기능을 갖춘 igxGrid가 구현되는 방법에 대한 자세한 예를 찾을 수 있습니다.
Using igxHierarchicalTransactionService
igxHierarchicalTransactionService extends igxTransactionService.
The igxHierarchicalTransactionService is designed to handle the relations between parents and children (use this when you have a hierarchical data structure, as in igxTreeGrid, for example). The service ensures that a new record will be added to the place you expect when adding an ADD transaction. When you delete a parent record, its' children will be promoted to the higher level of hierarchy, or will be deleted with their parent, depending on implementation. You can see the cascadeOnDelete property of the tree grid for a concrete example - depending on the value, deleting a parent record will have different effects on its children.
애플리케이션에서 사용자가 이미 삭제되어 트랜잭션이 커밋되기를 기다리고 있는 상위 레코드에 하위 레코드를 추가하려고 시도하는 시나리오를 처리할 수 있습니다. Transaction Service에서는 삭제될 상위 레코드에 레코드를 추가하는 것을 허용하지 않으며 콘솔에 오류 메시지가 표시됩니다. 그러나 다음 코드를 사용하여 상위 요소가 삭제되는지 확인하고 사용자에게 경고를 구현할 수 있습니다.
const state = this.transactions.getState(parentRecordID);
if (state && state.type === TransactionType.DELETE) {
// Implement your logic here
}
You may find a detailed examples of how igxTreeGrid and igxHierarchicalGrid with Batch Editing are implemented in the following topics:
Transaction Factory
In the concrete implementation of transactions inside of Ignite UI for Angular grids, a factory is used in order to instantiate the proper transaction service, depending on the value of the grid's batchEditing. There are two separate transaction factories - the IgxFlatTransactionFactory (used for Grid and Hierarchical Grid) and IgxHierarchicalTransactionFactory (used for Tree Grid). Both classes expose only one method - create - which returns a new instance of the proper type. The parameter passed (TRANSACTION_TYPE) is internally used - None is used when batchEditing is false and Base - when batch editing is enabled. An enum is used (instead of a true - false flag), as it allows to be expanded upon.
Using Transaction Factory
Both IgxFlatTransactionFactory and IgxHierarchicalTransactionFactory are provided in root and are exposed in the public API. If you want to instantiate a new instance of a transaction service, depending on some arbitrary check, you can use a transaction factory.
In the below example, you can see how you can instantiate different transaction services depending on an arbitrary (hasUndo) flag:
import { IgxFlatTransactionFactory, TRANSACTION_TYPE } from 'igniteui-angular/core';
// import { IgxFlatTransactionFactory, TRANSACTION_TYPE } from '@infragistics/igniteui-angular'; for licensed package
export class MyCustomComponent {
...
constructor(private transactionFactory: IgxFlatTransactionFactory) {}
...
public transaction!: IgxTransactionService<Transaction, State>;
public set hasUndo(val: boolean) {
if (val) {
this.transactions = this.transactionFactory.create(TRANSACTION_TYPE.Base);
} else {
this.transactions = this.transactionFactory.create(TRANSACTION_TYPE.None);
}
}
}
Both factory classes can be extended and overridden in the DI hierarchy (using the providers array) in order to provide your own, custom implementation. This, combined with the fact that all of the classes the get instantiated by the factories are also public, gives you a lot of control over what's provided to the components that use transaction implementations internally.
For example, to override the transaction service used internally by the IgxGridComponent, you can do the following:
먼저 사용자 정의 팩토리 클래스를 정의합니다.
import { IgxFlatTransactionFactory, TRANSACTION_TYPE, IgxBaseTransactionService,
TransactionService, Transaction, State } from 'igniteui-angular/core';
// import { IgxFlatTransactionFactory, TRANSACTION_TYPE, IgxBaseTransactionService,
// TransactionService, Transaction, State } from '@infragistics/igniteui-angular'; for licensed package
class CustomTransactionService extends IgxBaseTransactionService {
...
}
export class CustomTransactionFactory extends IgxFlatTransactionFactory {
...
create(type: TRANSACTION_TYPE): TransactionService<Transaction, State> {
if (type === TRANSACTION_TYPE.Base) {
return new CustomTransactionService();
}
super.create(type);
}
}
Then, in your component's providers array, override the IgxFlatTransactionFactory (used by igx-grid) with your custom implementation.
import { IgxFlatTransactionFactory } from 'igniteui-angular/core';
// import { IgxFlatTransactionFactory } from '@infragistics/igniteui-angular'; for licensed package
import { CustomTransactionFactory } from '../custom-factory.ts';
@Component({
selector: 'app-grid-view',
template: `<igx-grid [batchEditing]="true" [data]="data" [autoGenerate]="true"></igx-grid>`,
providers: [{ provide: IgxFlatTransactionFactory, useClass: CustomTransactionFactory }]
})
export class GridViewComponent {
...
}
Now, when batchEditing is set to true, the grid will receive an instance of CustomTransactionService.