Edición por lotes y transacciones en cuadrículas jerárquicas Angular
La función de edición por lotes de IgxHierarchicalGrid se basa en TransactionService
. Siga el tema Transaction Service class hierarchy
para ver una descripción general de igxTransactionService
y detalles sobre cómo se implementa.
Para utilizar HierarchicalTransactionService
con IgxHierarchicalGrid
, pero acumular registros de transacciones separados para cada isla, se debe proporcionar una fábrica de servicios. Uno se exporta y está listo para usar como IgxHierarchicalTransactionServiceFactory
.
A continuación se muestra un ejemplo detallado de cómo se habilita la edición por lotes para el componente Cuadrícula jerárquica.
Ejemplo de edición por lotes y transacciones en cuadrícula jerárquica Angular
El siguiente ejemplo muestra un escenario en el que hierarchicalGrid tiene habilitada batchEditing
y la edición de filas. Esto último garantizará que la transacción se agregue después de que se confirme la edición completa de la fila.
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 コピー
¿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.
El estado de la transacción consta de todas las filas actualizadas, agregadas y eliminadas, y sus últimos estados.
Uso
Para comenzar, importe IgxHierarchicalGridModule
en el archivo app.module.ts :
...
import { IgxHierarchicalGridModule } from 'igniteui-angular' ;
@NgModule ({
...
imports : [..., IgxHierarchicalGridModule],
...
})
export class AppModule {}
typescript
Luego, todo lo que necesitas hacer es habilitar batchEditing
desde tu cuadrícula jerárquica:
<igx-hierarchical-grid [data ]="data" [batchEditing ]="true" >
...
</igx-hierarchical-grid >
html
Esto garantizará que se proporcione una instancia adecuada del servicio Transaction
para igx-hierarchical-grid. El TransactionService
adecuado se proporciona a través de TransactionFactory
. Puede obtener más información sobre esta implementación interna en el tema de transacciones .
Después de habilitar la edición por lotes, defina un IgxHierarchicalGrid
con la fuente de datos vinculada y rowEditable
establecido en verdadero y vincule:
<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
El siguiente código demuestra el uso de la API transactions
: deshacer, rehacer y confirmar.
...
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
La API de transacciones no se encargará del final de la edición y deberá hacerlo usted mismo. De lo contrario, Hierarchical Grid
permanecería en modo de edición. Una forma de hacerlo es llamando endEdit
en el método respectivo.
Al deshabilitar la propiedad rowEditable
se modificará Hierarchical Grid
para crear transacciones en el cambio de celda y no se expondrá la superposición de edición de filas en la interfaz de usuario.
Referencias de API
Recursos adicionales
Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.