Cómo utilizar el servicio de transacciones

    Puedes beneficiarteTransaction Service de la opción de usar cualquier componente que necesite preservar el estado de su fuente de datos y comprometer muchas transacciones a la vez.

    Al trabajar con los componentes de Ignite UI for Angular cuadrícula, puedes usar losigxTransactionService yigxHierarchicalTransactionService que están integrados con las cuadrículas y ofrecen edición por lotes desde el primer momento. Sin embargo, si necesitas usar transacciones con cualquier otro componente Ignite UI for Angular o personalizado, puedes volver a usar eigxTransactionService implementar un comportamiento similar.

    Angular How to use the Transaction service Example

    En este tema utilizaremosigxList componentes para demostrar cómo habilitar transacciones. Demostraremos cómo añadir transacciones, cómo transformar los datos a través de una tubería y cómo actualizar visualmente la vista para que el usuario vea los cambios que están a punto de ser confirmados.

    Include Transaction Service

    Include Transaction Service in project

    Tenemos dos opciones para incluirIgxTransactionService en nuestra solicitud. La primera es añadirlo aAppModule otro módulo padre de la aplicación, como se hace en la demo anterior:

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

    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 { }
    

    Inject Transaction Service in component

    En nuestrots archivo, deberíamos importarigxTransactionService desde laigniteui-angular biblioteca, así como lasState interfaces yTransaction enumTransactionType, que serán necesarias para nuestra aplicación:

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

    Luego, Transaction Service debe importarse en el constructor:

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

    Define igxList

    En nuestra plantilla html, definimos unigxList componente con acciones de editar, eliminar y añadir, 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>
    

    Pipe for pending changes

    El componente de lista mencionado anteriormente utiliza eltransactionBasePipe para mostrar los cambios en los elementos de la lista de deseos sin afectar los datos originales. Así es como es 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;
        }
    }
    

    Edit, delete, add functionality

    Define edit functionality

    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>
    

    Cuando se pulsa el botón, dentro delonEdit gestor de eventos se crea una transacción 'ACTUALIZACIÓN':

    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]);
    }
    

    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;
    }
    

    Define delete functionality

    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>
    

    Cuando se pulsa el botón, dentroonDelete del gestor de eventos 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]);
    }
    

    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;
    }
    

    Define add functionality

    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>```
    

    Cuando se pulsa el botón, dentro delonAdd gestor de eventos se crea una transacción 'AÑADIR':

    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 });
    }
    

    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;
    }
    

    Transaction Log

    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>
    
    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);
        });
    }
    

    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>
    

    Commit pending transactions

    Una vez que terminamos todos nuestros cambios, podemos comprometerlos todos de una vez usando elcommit método de laigxTransactionService. Aplica todas las transacciones sobre los datos proporcionados:

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

    Si usamos eligxHierarchicalTransactionService, también podemos usar una sobrecarga delcommit método que espera primaryKey e childDataKey como argumentos.

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

    Clear pending transactions

    En cualquier momento de nuestra interacción con la lista, podemos borrar el registro de Transacciones usando elclear método.

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

    Additional Resources