Hierarquia de classe do Serviço de Transação

    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.

    Você pode ver um exemplo de como adicionar cada tipo de transação no tópico Como usar o serviço de transação.

    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.

    Como o estado acumulado é um objeto parcial, também podemos usar o serviço para verificar qual célula foi editada e criar uma interface de usuário em torno disso.

    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.

    Em ambos os casos (edição de células e edição de linhas), o estado das edições da grade consiste em todas as linhas atualizadas, adicionadas e excluídas e seus últimos estados. Elas podem ser inspecionadas, manipuladas e enviadas posteriormente de uma vez ou por id. As alterações são coletadas para células ou linhas individuais, dependendo do modo de edição, e acumuladas por linha/registro de dados.

    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.

    Você pode encontrar um exemplo detalhado de como o igxGrid com edição em lote é implementado no seguinte tópico:

    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.

    Em seu aplicativo, você pode querer lidar com o cenário em que o usuário tenta adicionar um registro filho a um registro pai que já foi excluído e está esperando a transação ser confirmada. O Transaction Service não permitirá adicionar um registro a um pai que deve ser excluído e uma mensagem de erro será exibida no Console. No entanto, você pode verificar se um pai deve ser excluído e implementar seu próprio alerta para o usuário usando o seguinte código:

        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:

    Primeiro, defina uma classe de fábrica personalizada

    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.

    Additional Resources