Cómo utilizar el servicio de transacciones

    Puede aprovechar el Transaction Service cuando utilice cualquier componente que necesite preservar el estado de su fuente de datos y realizar muchas transacciones a la vez.

    Al trabajar con los componentes de cuadrícula Ignite UI for Angular, puede utilizar el igxTransactionService y igxHierarchicalTransactionService que están integrados con las cuadrículas y proporcionan edición por lotes lista para usar. Sin embargo, si necesita usar transacciones con cualquier otro componente Ignite UI for Angular o personalizado, puede volver a usar el e implementar un igxTransactionService comportamiento similar.

    Angular Cómo utilizar el servicio de transacciones Ejemplo

    En este tema usaremos el componente igxList para demostrar cómo habilitar transacciones. Demostraremos cómo agregar transacciones, cómo transformar los datos a través de una tubería y cómo actualizar visualmente la vista para permitir al usuario ver los cambios que están a punto de confirmarse.

    EXAMPLE
    TS
    HTML
    SCSS

    ¿Te gusta esta muestra? Obtenga acceso a nuestro kit de herramientas de Ignite UI for Angular completo y comience a crear sus propias aplicaciones en minutos. Descárgalo gratis.

    Incluir servicio de transacciones

    Incluir el servicio de transacciones en el proyecto

    Tenemos dos opciones para incluir IgxTransactionService en nuestra aplicación. La primera es agregarlo a AppModule u otro módulo principal en la aplicación, como se hace en la demostración anterior:

    @NgModule({
        ...
        providers: [
            IgxTransactionService
        ]
    })
    export class AppModule { }
    typescript

    La otra opción es proporcionarlo en el componente donde se utiliza el servicio de transacciones:

    @Component({
        selector: 'transaction-base',
        styleUrls: ['./transaction-base.component.scss'],
        templateUrl: 'transaction-base.component.html',
        providers: [IgxTransactionService]
    })
    export class TransactionBaseComponent { }
    typescript

    Inyectar servicio de transacciones en el componente

    En nuestro archivo ts, debemos importar igxTransactionService de la biblioteca igniteui-angular, así como las interfaces State y Transaction y la enumeración TransactionType, que será necesaria para nuestra aplicación:

    import { IgxTransactionService, State, Transaction, TransactionType } from 'igniteui-angular';
    // import { IgxTransactionService, State, Transaction, TransactionType } from '@infragistics/igniteui-angular'; for licensed package
    typescript

    Luego, Transaction Service debe importarse en el constructor:

    constructor(private _transactions: IgxTransactionService<Transaction, State>) { ... }
    typescript

    Definir igxList

    En nuestra plantilla html, definimos un componente igxList con acciones editar, eliminar y agregar, que modifican la lista y sus elementos:

    <igx-list>
        <igx-list-item [isHeader]="true">Wishlist</igx-list-item>
        <igx-list-item *ngFor="let item of this.wishlist | transactionBasePipe"
            [ngClass]="{ deleted: isDeleted(item.id), edited: isEdited(item.id) }">
            <p igxListLineTitle>{{item.name}}</p>
            <p igxListLineSubTitle>Costs: {{item.price}}</p>
            <igx-icon igxListAction (click)="onEdit()" *ngIf="item.id === 1 && item.price !== '$999'">edit</igx-icon>
            <igx-icon igxListAction (click)="onDelete()" *ngIf="item.id === 2 && !isDeleted(item.id)">delete</igx-icon>
        </igx-list-item>
        <button igxButton (click)="onAdd()" [disabled]="itemAdded(4)">Add New</button>
    </igx-list>
    html

    Tubería para cambios pendientes

    El componente de lista anterior utiliza transactionBasePipe para mostrar cambios en los elementos de la lista de deseos sin afectar los datos originales. Así es como se ve la tubería:

    @Pipe({
        name: 'transactionBasePipe',
        pure: false
    })
    export class TransactionBasePipe implements PipeTransform {
        /**
         * @param transactions Injected Transaction Service.
         */
        constructor(public transactions: IgxTransactionService<Transaction, State>) { }
    
        public transform(data: WishlistItem[]) {
            // the pipe should NOT operate on the original dataset
            // we create a copy of the original data and then use it for visualization only
            const _data = [...data];
            const pendingStates = this.transactions.getAggregatedChanges(false);
    
            for (const state of pendingStates) {
                switch (state.type) {
                    case TransactionType.ADD:
                        // push the newValue property of the current `ADD` state
                        _data.push(state.newValue);
                        break;
                    case TransactionType.DELETE:
                        // pipe doesn't delete items because the demo displays them with a different style
                        // the record will be deleted once the state is committed
                        break;
                    case TransactionType.UPDATE:
                        const index = _data.findIndex(x => x.id === state.id);
                        // merge changes with the item into a new object
                        // to avoid modifying the original data item
                        _data[index] = Object.assign({}, _data[index], state.newValue);
                        break;
                    default:
                        return _data;
                }
            }
    
            return _data;
        }
    }
    typescript
    App Builder | CTA Banner

    Editar, eliminar, agregar funcionalidad

    Definir la funcionalidad de edición

    El segundo elemento de la lista contiene un botón de edición, que actualiza los datos del elemento.

    <igx-icon igxListAction (click)="onEdit()" *ngIf="item.id === 1 && item.price !== '$999'">edit</igx-icon>
    html

    Cuando se presiona el botón, dentro del controlador de eventos onEdit, se crea una transacción 'ACTUALIZAR':

    public onEdit(): void {
        const newPrice = "$999";
        // there can be multiple `UPDATE` transactions for the same item `id`
        // the `newValue` property should hold only the changed properties
        const editTransaction: Transaction = {
            id: this.wishlist[0].id,
            type: TransactionType.UPDATE,
            newValue: { price: newPrice }
        };
        // provide the first wishlist item as a `recordRef` argument
        this.transactions.add(editTransaction, this.wishlist[0]);
    }
    typescript

    Además, hay una función que verifica los elementos en busca de ediciones no guardadas:

    public isEdited(id): boolean {
        const state = this.transactions.getState(id);
        return state && state.type === TransactionType.UPDATE;
    }
    typescript

    Definir la funcionalidad de eliminación

    El tercer elemento de la lista contiene un botón de eliminación, que elimina los datos del elemento.

    <igx-icon igxListAction (click)="onDelete()" *ngIf="item.id === 2 && !isDeleted(item.id)">delete</igx-icon>
    html

    Cuando se presiona el botón, dentro del controlador de eventos onDelete, se crea una transacción 'ELIMINAR':

    public onDelete(): void {
        // after a `DELETE` transaction, no further changes should be made for the same `id`
        // the `newValue` property should be set to `null` since we do not change any values,
        const deleteTransaction: Transaction = {
            id: this.wishlist[1].id,
            type: TransactionType.DELETE,
            newValue: null
        };
        // provide the second wishlist item as a `recordRef` argument
        this.transactions.add(deleteTransaction, this.wishlist[1]);
    }
    typescript

    Además, existe una función que comprueba si los elementos se han eliminado sin guardar:

    public isDeleted(id): boolean {
        const state = this.transactions.getState(id);
        return state && state.type === TransactionType.DELETE;
    }
    typescript

    Definir agregar funcionalidad

    Al final de la lista se agrega un botón AGREGAR, que agrega un nuevo elemento a la lista.

    <button igxButton (click)="onAdd()" [disabled]="itemAdded(4)">Add New</button>```
    html

    Cuando se presiona el botón, dentro del controlador de eventos onAdd, se crea una transacción 'ADD':

    public onAdd(): void {
        // it must have a unique 'id' property
        const item: WishlistItem = { id: 4, name: 'Yacht', price: 'A lot!' };
    
        // in an `ADD` transaction you do not need to provide a `recordRef` argument,
        // since there is nothing to refer to yet
        this.transactions.add({ id: 4, type: TransactionType.ADD, newValue: item });
    }
    typescript

    Además, hay una función que comprueba si hay elementos añadidos no guardados:

    public itemAdded(id: number): boolean {
        const found = this.transactions.getState(id) || this.wishlist.find(x => x.id === 4);
        return !!found;
    }
    typescript

    Registro de transacciones

    La demostración muestra las transacciones pendientes dentro de un registro:

    <div>
        <h5>Transaction Log</h5>
        <div *ngFor="let transaction of this.getTransactionLog()">
            {{transaction.type.toUpperCase()}} -> {{transaction.name}} Costs: {{transaction.price}}
        </div>
    </div>
    html
    public getTransactionLog(): any[] {
        return this.transactions.getTransactionLog().map(transaction => {
            const item = this.wishlist.find(x => x.id === transaction.id);
            return Object.assign({ type: transaction.type }, item, transaction.newValue);
        });
    }
    typescript

    También agregaremos una representación del estado actual de nuestra lista. Mostrará cómo se ven los datos antes de que se confirmen las transacciones pendientes:

    <div>
        <h5>Data Items</h5>
        <div *ngFor="let item of this.wishlist">
            <div>{{item.name}} - {{item.price}}</div>
        </div>
    </div>
    html

    Confirmar transacciones pendientes

    Una vez que hayamos terminado con todos nuestros cambios, podemos confirmarlos todos a la vez usando el método commit de igxTransactionService. Aplica todas las transacciones sobre los datos proporcionados:

    <button igxButton="contained" (click)="onCommit()" [disabled]="this.getTransactionLog().length === 0">Commit Transactions</button>
    html
    public onCommit(): void {
        // the `commit` function expects the original data array as its parameter
        this.transactions.commit(this.wishlist);
    }
    
    typescript

    Si usamos igxHierarchicalTransactionService también podemos usar una sobrecarga del método commit que espera PrimaryKey y ChildDataKey como argumentos.

    public onCommit(): void {
        this.transactions.commit(this.wishlist, primaryKey, childDataKey);
    }
    typescript

    Borrar transacciones pendientes

    En cualquier punto de nuestra interacción con la lista, podemos borrar el registro de transacciones utilizando el método clear.

    <button igxButton="contained" (click)="onClear()" [disabled]="this.getTransactionLog().length === 0">Clear Transactions</button>
    html
    public onClear(): void {
        this.transactions.clear();
    }
    
    typescript

    Recursos adicionales