거래 서비스 이용 방법
데이터 소스 상태를 유지하고 여러 트랜잭션을 동시에 커밋해야 하는 컴포넌트를 사용할 때 이 이점을Transaction Service 누릴 수 있습니다.
Ignite UI for Angular 그리드 컴포넌트를 다룰 때는 그리드와 통합된 andigxTransactionService를 사용igxHierarchicalTransactionService 해 기본 배치 편집을 할 수 있습니다. 하지만 다른 Ignite UI for Angular 나 커스텀 컴포넌트와 트랜잭션을 사용해야 한다면, 다시 해당 트랜잭션을 사용하고igxTransactionService 유사한 동작을 구현할 수 있습니다.
Angular How to use the Transaction service Example
이 주제에서는 컴포넌트를 사용igxList 해 거래를 활성화하는 방법을 시연할 것입니다. 트랜잭션을 추가하는 방법, 파이프를 통한 데이터 변환 방법, 그리고 사용자가 커밋될 변경 사항을 볼 수 있도록 뷰를 시각적으로 업데이트하는 방법을 시연할 것입니다.
Include Transaction Service
Include Transaction Service in project
저희는 지원서에 포함IgxTransactionService 시킬 두 가지 옵션이 있습니다. 첫 번째는 위 데모에서 하는 것처럼 애플리케이션 내 다른 상위 모듈에AppModule 추가하는 것입니다:
@NgModule({
...
providers: [
IgxTransactionService
]
})
export class AppModule { }
다른 옵션은 트랜잭션 서비스가 사용되는 구성 요소에 이를 제공하는 것입니다.
@Component({
selector: 'transaction-base',
styleUrls: ['./transaction-base.component.scss'],
templateUrl: 'transaction-base.component.html',
providers: [IgxTransactionService]
})
export class TransactionBaseComponent { }
Inject Transaction Service in component
우리ts 파일을 가져와야 해igxTransactionServiceigniteui-angular 도서관과State 그리고Transaction 인터페이스 및TransactionType enum은 우리 애플리케이션에 필요합니다:
import { IgxTransactionService, State, Transaction, TransactionType } from 'igniteui-angular/core';
// import { IgxTransactionService, State, Transaction, TransactionType } from '@infragistics/igniteui-angular'; for licensed package
그런 다음 트랜잭션 서비스를 생성자에서 가져와야 합니다.
constructor(private _transactions: IgxTransactionService<Transaction, State>) { ... }
Define igxList
우리 HTML 템플릿에서는 다음을 정의합니다igxList 구성 요소는 편집하다, 삭제하다 그리고 추가 목록과 그 항목을 수정하는 액션:
<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
위에서 언급한 리스트 컴포넌트는 원본 데이터에 영향을 주지 않고 위시리스트 항목의 변경 사항을 표시하는 데 사용됩니다transactionBasePipe. 파이프는 다음과 같이 생겼습니다:
@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
두 번째 목록 항목에는 항목의 데이터를 업데이트하는 편집 버튼이 포함되어 있습니다.
<igx-icon igxListAction (click)="onEdit()" *ngIf="item.id === 1 && item.price !== '$999'">edit</igx-icon>
버튼을 누르면 이벤트 핸들러onEdit 내에서 'UPDATE' 트랜잭션이 생성됩니다:
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]);
}
또한 항목에 저장되지 않은 편집 내용을 확인하는 기능이 있습니다.
public isEdited(id): boolean {
const state = this.transactions.getState(id);
return state && state.type === TransactionType.UPDATE;
}
Define delete functionality
세 번째 목록 항목에는 항목의 데이터를 삭제하는 삭제 버튼이 포함되어 있습니다.
<igx-icon igxListAction (click)="onDelete()" *ngIf="item.id === 2 && !isDeleted(item.id)">delete</igx-icon>
버튼을 누르면 이벤트 핸들러 내부onDelete에서 'DELETE' 트랜잭션이 생성됩니다:
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]);
}
또한 저장되지 않은 삭제 항목을 확인하는 기능이 있습니다.
public isDeleted(id): boolean {
const state = this.transactions.getState(id);
return state && state.type === TransactionType.DELETE;
}
Define add functionality
목록 끝에 새 항목을 목록에 추가하는 ADD 버튼이 추가됩니다.
<button igxButton (click)="onAdd()" [disabled]="itemAdded(4)">Add New</button>```
버튼을 누르면 이벤트 핸들러onAdd 내에서 '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 });
}
또한 저장되지 않은 추가 항목을 확인하는 기능이 있습니다.
public itemAdded(id: number): boolean {
const found = this.transactions.getState(id) || this.wishlist.find(x => x.id === 4);
return !!found;
}
Transaction 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);
});
}
또한 목록의 현재 상태에 대한 표현을 추가할 것입니다. 보류 중인 트랜잭션이 커밋되기 전에 데이터가 어떻게 보이는지 보여줍니다.
<div>
<h5>Data Items</h5>
<div *ngFor="let item of this.wishlist">
<div>{{item.name}} - {{item.price}}</div>
</div>
</div>
Commit pending transactions
모든 변경 사항을 마치면, 우리는 하나의 메서드commit를 사용하여igxTransactionService 한 번에 모두 커밋할 수 있습니다. 제공된 데이터에 대한 모든 트랜잭션을 적용합니다:
<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);
}
만약 를igxHierarchicalTransactionService 사용한다면, primaryKey와 childDataKey를 인수로 기대하는 메서드의commit 오버로드도 사용할 수 있습니다.
public onCommit(): void {
this.transactions.commit(this.wishlist, primaryKey, childDataKey);
}
Clear pending transactions
리스트와 상호작용하는 어느 시점에서든, 이clear 방법을 사용해 트랜잭션 로그를 삭제할 수 있습니다.
<button igxButton="contained" (click)="onClear()" [disabled]="this.getTransactionLog().length === 0">Clear Transactions</button>
public onClear(): void {
this.transactions.clear();
}