Jerarquía de clases de servicios de transacciones

    Transaction, State, Transaction Log

    La Transacción es el componente principal del servicio de Transacción. La transacción es en realidad cada operación que ejecuta con los datos. La interfaz Transaction define tres propiedades: id, newValue y type.

    La id de la transacción debe ser única por registro de datos y define el registro al que afecta esta transacción. El type puede ser cualquiera de los tres tipos de transacción: ADD, DELETE y UPDATE, dependiendo de la operación que ejecute. El newValue contiene el valor del nuevo registro en caso de que esté agregando una transacción ADD. Si está actualizando un registro existente, el newValue contendrá solo los cambios. Es posible que tenga varias transacciones del tipo UPDATE con la misma identificación. Si está eliminando un registro, el newValue contendrá el valor del registro eliminado.

    Puede ver un ejemplo de cómo se ve agregar cada tipo de transacción en el tema Cómo utilizar el servicio de transacciones.

    Cada vez que agrega una transacción, se agrega al registro de transacciones y a la pila de deshacer. Luego, todos los cambios en el registro de transacciones se acumulan por registro. A partir de ese punto, el servicio mantiene un State agregado. El State consta de registros únicos y cada registro puede ser de uno de los tipos de transacciones admitidos, mencionados anteriormente.

    Mientras agrega transacciones, puede activar transacciones pendientes llamando startPending. Todas las transacciones posteriores se acumularán en una sola transacción hasta que llame endPending. Si pasa true a endPending todas las transacciones acumuladas se agregarán como una sola transacción en el registro de transacciones y en la pila de deshacer.

    Using igxBaseTransaction

    Nuestro módulo de cuadrícula proporciona una implementación muy básica del servicio de transacciones (igxBaseTransactionService) con la funcionalidad de sesión pendiente que permite la función de edición de filas. Al utilizar startPending y endPending Row, la edición puede combinar múltiples operaciones por celda en un solo cambio. Esto significa que editar varias celdas de un solo registro crea una única transacción y usted puede manejar solo el evento de edición de fila.

    Dado que el estado acumulado es un objeto parcial, también podemos usar el servicio para verificar qué celda se ha editado y crear una interfaz de usuario en torno a eso.

    igxBaseTransactionService no tiene pila de deshacer, por lo que no proporciona funcionalidad de deshacer/rehacer.

    En los siguientes temas se proporciona un ejemplo detallado de cómo puede usar igxBaseTransactionService para habilitar la edición de filas:

    General information on igxTransactionService and igxHierarchicalTransactionService

    igxTransactionService e igxHierarchicalTransactionService son middlewares inyectables que implementan la interfaz Transaction Service. Un componente puede usarlos para acumular cambios sin afectar los datos subyacentes. El proveedor expone la API para acceder, manipular (deshacer y rehacer) y descartar o confirmar uno o todos los cambios en los datos.

    En un ejemplo más concreto, igxTransactionService e igxHierarchicalTransactionService pueden funcionar tanto con la edición de celdas como con la edición de filas de IgxGrid. La transacción para la edición de celda se agrega cuando la celda sale del modo de edición. Cuando comienza la edición de filas, la cuadrícula establece su servicio de transacciones en estado pendiente llamando startPending. Cada celda editada se agrega al registro de transacciones pendientes y no se agrega al registro de transacciones principal. Cuando la fila sale del modo de edición, todos los cambios se agregan al registro de transacciones principal y al registro de deshacer como una sola transacción.

    En ambos casos (edición de celdas y edición de filas), el estado de las ediciones de la cuadrícula consta de todas las filas actualizadas, agregadas y eliminadas y sus últimos estados. Posteriormente, estos pueden inspeccionarse, manipularse y enviarse de una vez o por identificación. Los cambios se recopilan para celdas o filas individuales, según el modo de edición, y se acumulan por fila/registro de datos.

    Using igxTransactionService

    igxTransactionService extiende igxBaseTransactionService.

    Si desea que su componente utilice transacciones al realizar operaciones de datos, debe definir igxTransactionService como proveedor en la matriz providers de su componente.

    igxTransactionService proporciona una pila de deshacer para que pueda aprovechar la funcionalidad de deshacer/rehacer. La pila Deshacer es en realidad una matriz que contiene matrices de transacciones. Al utilizar igxTransactionService, puede verificar el descriptor canUndo para saber si hay transacciones en la pila Deshacer. Si los hay, puede utilizar el método undo para eliminar la última transacción y redo para aplicar la última transacción deshecha.

    Puede encontrar un ejemplo detallado de cómo se implementa igxGrid con edición por lotes en el siguiente tema:

    Using igxHierarchicalTransactionService

    igxHierarchicalTransactionService extiende igxTransactionService.

    igxHierarchicalTransactionService está diseñado para manejar las relaciones entre padres e hijos (úselo cuando tenga una estructura de datos jerárquica, como en igxTreeGrid, por ejemplo). El servicio garantiza que se agregará un nuevo registro al lugar esperado al agregar una transacción ADD. Cuando elimina un registro principal, sus hijos ascenderán al nivel superior de jerarquía o se eliminarán con su padre, según la implementación. Puede ver la propiedad cascadeOnDelete de la cuadrícula de árbol para ver un ejemplo concreto: según el valor, eliminar un registro principal tendrá diferentes efectos en sus hijos.

    En su aplicación, es posible que desee manejar el escenario en el que el usuario intenta agregar un registro secundario a un registro principal que ya está eliminado y está esperando que se confirme la transacción. El Servicio de transacciones no permitirá agregar un registro a un padre que se va a eliminar y se mostrará un mensaje de error en la Consola. Sin embargo, puede verificar si se va a eliminar un padre e implementar su propia alerta para el usuario usando el siguiente código:

        const state = this.transactions.getState(parentRecordID);
        if (state && state.type === TransactionType.DELETE) {
            // Implement your logic here
        }
    

    Puede encontrar ejemplos detallados de cómo se implementan igxTreeGrid e igxHierarchicalGrid con edición por lotes en los siguientes temas:

    Transaction Factory

    En la implementación concreta de transacciones dentro de Ignite UI for Angular grids, se utiliza una fábrica para crear una instancia del servicio de transacciones adecuado, dependiendo del valor de la batchEditing de la grid. Hay dos fábricas de transacciones separadas: IgxFlatTransactionFactory (usada para Grid y Hierarchical Grid) e IgxHierarchicalTransactionFactory (usada para Tree Grid). Ambas clases exponen sólo un método (create) que devuelve una nueva instancia del tipo adecuado. El parámetro pasado (TRANSACTION_TYPE) se usa internamente; None se usa cuando batchEditing es falsa y Base, cuando la edición por lotes está habilitada. Se utiliza una enum (en lugar de una bandera true-false), ya que permite ampliarla.

    Using Transaction Factory

    Tanto IgxFlatTransactionFactory como IgxHierarchicalTransactionFactory se proporcionan en root y se exponen en la API pública. Si desea crear una instancia nueva de un servicio de transacciones, dependiendo de alguna verificación arbitraria, puede utilizar una fábrica de transacciones.

    En el siguiente ejemplo, puede ver cómo puede crear instancias de diferentes servicios de transacciones dependiendo de un indicador arbitrario (hasUndo):

    import { IgxFlatTransactionFactory, TRANSACTION_TYPE } from 'igniteui-angular';
    // 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);
            }
        }
    }
    

    Ambas clases de fábrica se pueden ampliar y anular en la jerarquía DI (usando la matriz providers) para proporcionar su propia implementación personalizada. Esto, combinado con el hecho de que todas las clases de las que las fábricas crean instancias también son públicas, le brinda mucho control sobre lo que se proporciona a los componentes que utilizan implementaciones de transacciones internamente.

    Por ejemplo, para anular el servicio de transacciones utilizado internamente por IgxGridComponent, puede hacer lo siguiente:

    Primero, defina una clase de fábrica personalizada

    import { IgxFlatTransactionFactory, TRANSACTION_TYPE, IgxBaseTransactionService,
    TransactionService, Transaction, State } from 'igniteui-angular';
    // 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);
        }
    }
    
    

    Luego, en la matriz de providers de su componente, anule IgxFlatTransactionFactory (utilizado por igx-grid) con su implementación personalizada.

    import { IgxFlatTransactionFactory } from 'igniteui-angular';
    // 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 {
        ...
    }
    

    Ahora, cuando batchEditing se establece en true, la cuadrícula recibirá una instancia de CustomTransactionService.

    Additional Resources