Angular 계층형 그리드 일괄 편집 및 거래
IgxHierarchicalGrid의 일괄 편집 기능은 다음을 기반으로 합니다. TransactionService
. 따라가다 Transaction Service class hierarchy
주제에 대한 개요를 볼 수 있습니다. igxTransactionService
구현 방법을 자세히 설명합니다.
IgxHierarchicalGrid
와 함께 HierarchicalTransactionService
사용하되 각 아일랜드별로 별도의 트랜잭션 로그를 축적하게 하려면 서비스 팩토리를 대신 제공해야 합니다. 하나는 내보내지고 IgxHierarchicalTransactionServiceFactory
로 사용할 준비가 되었습니다.
다음은 계층형 그리드 구성 요소에 대해 일괄 편집을 활성화하는 방법에 대한 자세한 예입니다.
Angular 계층형 그리드 일괄 편집 및 거래 예
다음 샘플은 hierarchicalGrid에 batchEditing
활성화되고 행 편집이 활성화된 시나리오를 보여줍니다. 후자는 전체 행 편집이 확인된 후 트랜잭션이 추가되도록 보장합니다.
import { Component, OnInit, ViewChild } from '@angular/core' ;
import { IgxDialogComponent, IgxHierarchicalGridComponent, IgxRowIslandComponent, Transaction, IgxButtonDirective, IgxColumnComponent, IgxCellTemplateDirective, IgxGridToolbarDirective, IgxGridToolbarComponent, IgxInputGroupComponent, IgxLabelDirective, IgxInputDirective, IgxCheckboxComponent, IgxGridComponent } from 'igniteui-angular' ;
import { SINGERS } from '../../data/singersData' ;
import { Singer } from '../models' ;
import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scroll.directive' ;
import { FormsModule } from '@angular/forms' ;
@Component ({
selector : 'app-hierarchical-grid-batch-editing' ,
styleUrls : ['./hierarchical-grid-batch-editing.component.scss' ],
templateUrl : 'hierarchical-grid-batch-editing.component.html' ,
imports : [IgxButtonDirective, IgxHierarchicalGridComponent, IgxPreventDocumentScrollDirective, IgxColumnComponent, IgxCellTemplateDirective, IgxRowIslandComponent, IgxGridToolbarDirective, IgxGridToolbarComponent, IgxDialogComponent, IgxInputGroupComponent, IgxLabelDirective, FormsModule, IgxInputDirective, IgxCheckboxComponent, IgxGridComponent]
})
export class HGridBatchEditingSampleComponent implements OnInit {
@ViewChild ('dialogChanges' , { read : IgxDialogComponent, static : true })
public dialogChanges: IgxDialogComponent;
@ViewChild ('childGrid' , { static : true })
private childGrid: IgxRowIslandComponent;
@ViewChild ('hierarchicalGrid' , { static : true })
private hierarchicalGrid: IgxHierarchicalGridComponent;
@ViewChild ('dialogAddSinger' , { read : IgxDialogComponent, static : true })
private dialogSinger: IgxDialogComponent;
public get undoEnabledParent (): boolean {
return this .hierarchicalGrid.transactions.canUndo;
}
public get redoEnabledParent (): boolean {
return this .hierarchicalGrid.transactions.canRedo;
}
public get hasTransactions (): boolean {
return this .hierarchicalGrid.transactions.getAggregatedChanges(false ).length > 0 || this .hasChildTransactions;
}
public get hasChildTransactions (): boolean {
return this .childGrid.gridAPI.getChildGrids()
.find(c => c.transactions.getAggregatedChanges(false ).length > 0 ) !== undefined ;
}
public data: Singer[];
public singer: Singer;
public transactionsDataAll: Transaction[] = [];
private id = 14 ;
constructor ( ) {}
public ngOnInit(): void {
this .data = SINGERS;
this .singer = {
ID : this .id,
Artist : 'Mock Jagger' ,
Debut : 2005 ,
GrammyAwards : 4 ,
GrammyNominations : 7 ,
HasGrammyAward : false
};
}
public formatter = a => a;
public undo (grid: any ) {
const hGrid = grid as IgxHierarchicalGridComponent;
hGrid.endEdit(true );
hGrid.transactions.undo();
}
public redo (grid: any ) {
const hGrid = grid as IgxHierarchicalGridComponent;
hGrid.endEdit(true );
hGrid.transactions.redo();
}
public commit ( ) {
this .hierarchicalGrid.transactions.commit(this .data);
this .childGrid.gridAPI.getChildGrids().forEach((grid ) => {
grid.transactions.commit(grid.data);
});
this .dialogChanges.close();
}
public discard ( ) {
this .hierarchicalGrid.transactions.clear();
this .childGrid.gridAPI.getChildGrids().forEach((grid ) => {
grid.transactions.clear();
});
this .dialogChanges.close();
}
public openCommitDialog ( ) {
this .transactionsDataAll = [...this.hierarchicalGrid.transactions.getAggregatedChanges(true )];
this .childGrid.gridAPI.getChildGrids().forEach((grid ) => {
this .transactionsDataAll = this .transactionsDataAll.concat(grid.transactions.getAggregatedChanges(true ));
});
this .dialogChanges.open();
}
public addSinger ( ) {
this .hierarchicalGrid.addRow(this .singer);
++this .id;
this .cancel();
}
public removeRow (rowIndex ) {
const row = this .hierarchicalGrid.getRowByIndex(rowIndex);
row.delete();
}
public stateFormatter (value: string ) {
return JSON .stringify(value);
}
public typeFormatter (value: string ) {
return value.toUpperCase();
}
public classFromType(type : string ): string {
return `transaction--${type .toLowerCase()} ` ;
}
public cancel ( ) {
this .dialogChanges.close();
this .dialogSinger.close();
this .singer = {
ID : this .id,
Artist : 'Mock Jagger' ,
Debut : 2005 ,
GrammyAwards : 4 ,
GrammyNominations : 7 ,
HasGrammyAward : false
};
}
}
ts コピー <div class ="grid-wrapper" >
<button igxButton ="contained" (click )="dialogAddSinger.open()" class ="addSingerBtn" > Add Singer</button >
<igx-hierarchical-grid [igxPreventDocumentScroll ]="true" #hierarchicalGrid [batchEditing ]="true" class ="hgrid" [data ]="data"
[primaryKey ]="'Artist'" [height ]="'550px'" [width ]="'100%'" [rowEditable ]="true" >
<igx-column width ="150px" [editable ]="false" >
<ng-template igxCell let-cell ="cell" let-val >
<button igxButton (click )="removeRow(cell.id.rowIndex)"
[disabled ]="cell.row.deleted" > Delete</button >
</ng-template >
</igx-column >
<igx-column field ="Artist" header ="Artist" [editable ]="false" [dataType ]="'string'" > </igx-column >
<igx-column field ="HasGrammyAward" header ="Has Grammy Award?" [editable ]="true" [dataType ]="'boolean'" >
</igx-column >
<igx-column field ="Debut" header ="Debut" [editable ]="true" dataType ="number" [formatter ]="formatter" >
</igx-column >
<igx-column field ="GrammyNominations" header ="Grammy Nominations" [editable ]="true" dataType ="number" >
</igx-column >
<igx-column field ="GrammyAwards" header ="Grammy Awards" [editable ]="true" dataType ="number" > </igx-column >
<igx-row-island [height ]="null" #childGrid [key ]="'Albums'" [primaryKey ]="'Album'" [rowEditable ]="true" >
<igx-grid-toolbar *igxGridToolbar ="let grid" >
<button igxButton [disabled ]="!grid.transactions.canUndo" (click )="undo(grid)" > Undo</button >
<button igxButton [disabled ]="!grid.transactions.canRedo" (click )="redo(grid)" > Redo</button >
</igx-grid-toolbar >
<igx-column field ="Album" [editable ]="false" [dataType ]="'string'" > </igx-column >
<igx-column field ="LaunchDate" header ="Launch Date" [editable ]="true" [dataType ]="'date'" > </igx-column >
<igx-column field ="BillboardReview" header ="Billboard Review" [editable ]="true" dataType ="number" >
</igx-column >
<igx-column field ="USBillboard200" header ="US Billboard 200" [editable ]="true" dataType ="number" >
</igx-column >
</igx-row-island >
</igx-hierarchical-grid >
<div class ="buttons-row" >
<div class ="buttons-wrapper" >
<button igxButton [disabled ]="!hasTransactions" (click )="openCommitDialog()" > Commit</button >
<button igxButton [disabled ]="!undoEnabledParent" (click )="undo(hierarchicalGrid)" > Undo Parent</button >
<button igxButton [disabled ]="!redoEnabledParent" (click )="redo(hierarchicalGrid)" > Redo Parent</button >
</div >
</div >
<igx-dialog #dialogAddSinger title ="New Singer" [rightButtonLabel ]="'Add'" [leftButtonLabel ]="'Cancel'"
(leftButtonSelect )="cancel()" (rightButtonSelect )="addSinger()" >
<div class ="dialogNewSinger" >
<igx-input-group >
<label igxLabel for ="artist" > Artist</label >
<input igxInput id ="artist" type ="text" [(ngModel )]="singer.Artist" />
</igx-input-group >
<igx-checkbox id ="hasGrammyAward" [(ngModel )]="singer.HasGrammyAward" > Has Grammy Award</igx-checkbox >
<igx-input-group >
<label igxLabel for ="debut" > Debut</label >
<input igxInput id ="debut" type ="number" [(ngModel )]="singer.Debut" />
</igx-input-group >
<igx-input-group >
<label igxLabel for ="grammyNominations" > Grammy Nominations</label >
<input igxInput id ="grammyNominations" type ="number" [(ngModel )]="singer.GrammyNominations" />
</igx-input-group >
<igx-input-group >
<label igxLabel for ="grammyAwards" > Grammy Awards</label >
<input igxInput id ="grammyAwards" type ="number" [(ngModel )]="singer.GrammyAwards" />
</igx-input-group >
</div >
</igx-dialog >
<igx-dialog #dialogChanges title ="Submit the following transactions?" >
<igx-grid [igxPreventDocumentScroll ]="true" #dialogGrid [data ]="transactionsDataAll" [rowHeight ]="64" [primaryKey ]="'id'"
width ="650px" height ="300px" [emptyGridMessage ]="'No available transactions'" >
<igx-column field ="id" header ="ID" [dataType ]="'string'" width ="150px" > </igx-column >
<igx-column field ="type" header ="Type" width ="150px" [sortable ]="true" >
<ng-template igxCell let-cell ="cell" let-val >
<span [class ]="classFromType(val)" > {{ typeFormatter(val) }}</span >
</ng-template >
</igx-column >
<igx-column field ="newValue" header ="Value" width ="900px" >
<ng-template igxCell let-cell ="cell" let-val >
<span class ="transaction-log" > {{ stateFormatter(val) }}</span >
</ng-template >
</igx-column >
</igx-grid >
<div class ="buttons-wrapper" >
<button igxButton (click )="commit()" > Commit</button >
<button igxButton (click )="discard()" > Discard</button >
<button igxButton (click )="cancel()" > Cancel</button >
</div >
</igx-dialog >
</div >
html コピー h4 {
text-align : center;
padding-top : 2% ;
padding-bottom : 2% ;
}
.buttons-row {
display : flex;
flex-direction : row;
justify-content : space-between;
padding : 5px ;
}
.buttons-wrapper {
display : flex;
flex-direction : row;
justify-content : center;
padding : 10px 0 ;
}
.addSingerBtn .igx-button--contained {
margin-bottom : 10px ;
}
.dialogNewSinger {
> * {
margin-bottom : 8px ;
&:last-child {
margin-bottom : 0 ;
}
}
}
.igx-checkbox {
margin-top : 5px ;
margin-bottom : 5px ;
padding-top : 8px ;
padding-bottom : 5px ;
}
.transaction--update , .transaction--delete , .transaction--add {
font-weight : 600 ;
}
.transaction--add {
color : #6b3 ;
}
.transaction--update {
color : #4a71b9 ;
}
.transaction--delete {
color : #ee4920 ;
}
.transaction-log {
word-wrap : none;
}
.grid-wrapper {
padding : 16px ;
}
scss コピー
이 샘플이 마음에 드시나요? 전체 Ignite UI for Angular 툴킷에 액세스하고 몇 분 안에 나만의 앱을 구축해 보세요. 무료로 다운로드하세요.
트랜잭션 상태는 업데이트, 추가, 삭제된 모든 행과 마지막 상태로 구성됩니다.
용법
시작하려면 IgxHierarchicalGridModule
에서 app.module.ts 파일:
...
import { IgxHierarchicalGridModule } from 'igniteui-angular' ;
@NgModule ({
...
imports : [..., IgxHierarchicalGridModule],
...
})
export class AppModule {}
typescript
그런 다음 계층 그리드에서 batchEditing
활성화하기만 하면 됩니다.
<igx-hierarchical-grid [data ]="data" [batchEditing ]="true" >
...
</igx-hierarchical-grid >
html
이렇게 하면 igx-hierarchical-grid에 대해 적절한 Transaction
서비스 인스턴스가 제공됩니다. 적절한 TransactionService
TransactionFactory
통해 제공됩니다. 거래 주제 에서 이 내부 구현에 대해 자세히 알아볼 수 있습니다.
일괄 편집이 활성화된 후 IgxHierarchicalGrid
바인딩된 데이터 소스와 rowEditable
true로 설정하고 바인딩합니다.
<igx-hierarchical-grid #hierarchicalGrid [batchEditing ]="true" [data ]="data" [primaryKey ]="'Artist'"
[height ]="'580px'" [width ]="'100%'" [rowEditable ]="true" >
...
<igx-row-island #childGrid [key ]="'Albums'" [primaryKey ]="'Album'" [rowEditable ]="true" >
<igx-grid-toolbar > </igx-grid-toolbar >
...
<ng-template igxToolbarCustomContent let-grid ="grid" >
<button igxButton [disabled ]="!grid.transactions.canUndo" (click )="undo(grid)" > Undo</button >
<button igxButton [disabled ]="!grid.transactions.canRedo" (click )="redo(grid)" > Redo</button >
</ng-template >
</igx-row-island >
</igx-hierarchical-grid >
...
<div class ="buttons-row" >
<div class ="buttons-wrapper" >
<button igxButton [disabled ]="!undoEnabledParent" (click )="undo(hierarchicalGrid)" > Undo Parent</button >
<button igxButton [disabled ]="!redoEnabledParent" (click )="redo(hierarchicalGrid)" > Redo Parent</button >
</div >
</div >
...
html
다음 코드는 transactions
API(실행 취소, 다시 실행, 커밋)의 사용법을 보여줍니다.
...
export class HierarchicalGridBatchEditingSampleComponent {
public undo (grid: any ) {
grid.endEdit(true );
grid.transactions.undo();
}
public redo (grid: any ) {
grid.endEdit(true );
grid.transactions.redo();
}
public commit ( ) {
this .hierarchicalGrid.transactions.commit(this .data);
this .childGrid.hgridAPI.getChildGrids().forEach((grid ) => {
grid.transactions.commit(grid.data);
});
this .dialogChanges.close();
}
}
typescript
트랜잭션 API는 편집 종료를 처리하지 않으며 사용자가 직접 처리해야 합니다. 그렇지 않으면 Hierarchical Grid
편집 모드로 유지됩니다. 이를 수행하는 한 가지 방법은 해당 메소드에서 endEdit
호출하는 것입니다.
rowEditable
속성을 비활성화하면 Hierarchical Grid
수정되어 셀 변경 시 트랜잭션이 생성되고 UI에 행 편집 오버레이가 표시되지 않습니다.
API 참조
추가 리소스
우리 커뮤니티는 활동적이며 항상 새로운 아이디어를 환영합니다.