Como usar o serviço de transação
Você pode aproveitar oTransaction Service uso de qualquer componente que precise preservar o estado de sua fonte de dados e comprometer muitas transações ao mesmo tempo.
Ao trabalhar com os componentes Ignite UI for Angular grade, você pode usar osigxTransactionService eigxHierarchicalTransactionService que estão integrados às grades e oferecem edição em lote logo de fábrica. No entanto, se você precisar usar transações com qualquer outro componente Ignite UI for Angular ou personalizado, pode novamente usar eigxTransactionService implementar comportamentos semelhantes.
Angular How to use the Transaction service Example
Neste tópico, usaremosigxList o componente para demonstrar como habilitar transações. Vamos demonstrar como adicionar transações, como transformar os dados por meio de um pipeline e como atualizar visualmente a visualização para permitir que o usuário veja as mudanças que estão prestes a ser confirmadas.
Include Transaction Service
Include Transaction Service in project
Temos duas opções para incluirIgxTransactionService na nossa inscrição. A primeira é adicioná-la aAppModule outro módulo pai na aplicação, como é feito na demonstração acima:
@NgModule({
...
providers: [
IgxTransactionService
]
})
export class AppModule { }
A outra opção é fornecê-lo no componente onde o serviço de transação é usado:
@Component({
selector: 'transaction-base',
styleUrls: ['./transaction-base.component.scss'],
templateUrl: 'transaction-base.component.html',
providers: [IgxTransactionService]
})
export class TransactionBaseComponent { }
Inject Transaction Service in component
No nossots arquivo, devemos importarigxTransactionService daigniteui-angular biblioteca, assim como dasState interfaces eTransaction doTransactionType enum, que serão necessários para nossa aplicação:
import { IgxTransactionService, State, Transaction, TransactionType } from 'igniteui-angular/core';
// import { IgxTransactionService, State, Transaction, TransactionType } from '@infragistics/igniteui-angular'; for licensed package
Então o Transaction Service deve ser importado no construtor:
constructor(private _transactions: IgxTransactionService<Transaction, State>) { ... }
Define igxList
No nosso modelo html, definimos umigxList componente com ações de editar, excluir e adicionar, que modificam a lista e seus itens:
<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
O componente de lista acima usa otransactionBasePipe para exibir alterações nos itens da lista de desejos sem afetar os dados originais. Aqui está como o cano se apresenta:
@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
O segundo item da lista contém um botão de edição, que atualiza os dados do item.
<igx-icon igxListAction (click)="onEdit()" *ngIf="item.id === 1 && item.price !== '$999'">edit</igx-icon>
Quando o botão é pressionado, dentro doonEdit gerenciador de eventos, uma transação 'ATUALIZAÇÃO' é criada:
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]);
}
Além disso, há uma função que verifica itens em busca de edições não salvas:
public isEdited(id): boolean {
const state = this.transactions.getState(id);
return state && state.type === TransactionType.UPDATE;
}
Define delete functionality
O terceiro item da lista contém um botão de exclusão, que exclui os dados do item.
<igx-icon igxListAction (click)="onDelete()" *ngIf="item.id === 2 && !isDeleted(item.id)">delete</igx-icon>
Quando o botão é pressionado, dentroonDelete do gerenciador de eventos, uma transação 'DELETE' é criada:
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]);
}
Além disso, há uma função que verifica se há itens excluídos não salvos:
public isDeleted(id): boolean {
const state = this.transactions.getState(id);
return state && state.type === TransactionType.DELETE;
}
Define add functionality
No final da lista, é adicionado um botão ADICIONAR, que adiciona um novo item à lista.
<button igxButton (click)="onAdd()" [disabled]="itemAdded(4)">Add New</button>```
Quando o botão é pressionado, dentro doonAdd gerenciador de eventos, uma transação 'ADD' é criada:
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 });
}
Além disso, há uma função que verifica itens em busca de adições não salvas:
public itemAdded(id: number): boolean {
const found = this.transactions.getState(id) || this.wishlist.find(x => x.id === 4);
return !!found;
}
Transaction Log
A demonstração demonstra as transações pendentes dentro de um log:
<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);
});
}
Também adicionaremos uma representação do estado atual da nossa lista. Ela mostrará como os dados parecem antes das transações pendentes serem confirmadas:
<div>
<h5>Data Items</h5>
<div *ngFor="let item of this.wishlist">
<div>{{item.name}} - {{item.price}}</div>
</div>
</div>
Commit pending transactions
Quando terminarmos todas as nossas mudanças, podemos comprometê-las todas de uma vez usando ocommit método doigxTransactionService. Ele aplica todas as transações sobre os dados fornecidos:
<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);
}
Se estivermos usando o,igxHierarchicalTransactionService também podemos usar uma sobrecarga docommit método que espera primaryKey e childDataKey como argumentos.
public onCommit(): void {
this.transactions.commit(this.wishlist, primaryKey, childDataKey);
}
Clear pending transactions
Em qualquer momento da nossa interação com a lista, podemos limpar o registro de Transações, usando oclear método.
<button igxButton="contained" (click)="onClear()" [disabled]="this.getTransactionLog().length === 0">Clear Transactions</button>
public onClear(): void {
this.transactions.clear();
}