Angular 그리드 상태 지속성
igxGridState 지시문을 사용하면 개발자가 그리드 상태를 쉽게 저장하고 복원할 수 있습니다. IgxGridState
지시문이 그리드에 적용되면 개발자가 모든 시나리오에서 상태 지속성을 달성하는 데 사용할 수 있는 getState
및 setState
메서드가 노출됩니다.
지원되는 기능
IgxGridState
지시문은 다음 기능의 상태 저장 및 복원을 지원합니다.
Sorting
Filtering
Advanced Filtering
Paging
Cell Selection
Row Selection
Column Selection
Row Pinning
Expansion
GroupBy
Columns
이 Row Selection
기능을 사용하려면 primaryKey
속성을 올바르게 저장/복원할 수 있도록 속성을 설정해야 합니다.
용법
getState
- 이 방법은 직렬화된 JSON 문자열로 그리드 상태를 반환하므로 개발자는 이를 가져와 모든 데이터 저장소(데이터베이스, 클라우드, 브라우저 localStorage 등)에 저장할 수 있습니다. 이 메소드는 첫 번째 선택적 매개변수를 허용합니다. serialize
, 여부를 결정합니다. getState
반환합니다 IGridState
객체 또는 직렬화된 JSON 문자열. 개발자는 기능 이름 또는 기능 이름이 포함된 배열을 두 번째 인수로 전달하여 특정 기능에 대한 상태만 가져오도록 선택할 수 있습니다.
const gridState = state.getState();
const gridState: IGridState = state.getState(false );
const sortingFilteringStates: IGridState = state.getState(false , ['sorting' , 'filtering' ]);
typescript
setState
-setState
메소드는 직렬화된 JSON 문자열 또는 IGridState
객체를 인수로 받아들이고 객체/JSON 문자열에 있는 각 기능의 상태를 복원합니다.
state.setState(gridState);
state.setState(sortingFilteringStates)
typescript
options
-options
개체는 IGridStateOptions
인터페이스를 구현합니다. 즉, 특정 기능의 이름인 모든 키에 대해 이 기능 상태가 추적되는지 여부를 나타내는 부울 값이 있습니다. getState
메소드는 이러한 기능의 상태를 반환된 값에 넣지 않으며 setState
메소드는 해당 기능의 상태를 복원하지 않습니다.
public options = { cellSelection : false ; sorting: false ; }
typescript
<igx-grid [igxGridState ]="options" > </igx-grid >
html
사용하기 쉬운 단일 지점 API를 사용하면 단 몇 줄의 코드만으로 전체 상태 지속성 기능을 달성할 수 있습니다. 아래 코드를 복사하여 붙여넣으세요 . 사용자가 현재 페이지를 떠날 때마다 브라우저 sessionStorage
객체에 그리드 상태가 저장됩니다. 사용자가 메인 페이지로 돌아갈 때마다 그리드 상태가 복원됩니다. 원하는 데이터를 얻기 위해 매번 복잡한 고급 필터링 및 정렬 표현식을 구성할 필요가 없습니다. 한 번만 수행하면 아래 코드가 사용자를 위해 나머지 작업을 수행하게 됩니다.
@ViewChild (IgxGridStateDirective, { static : true })
public state!: IgxGridStateDirective;
public ngOnInit ( ) {
this .router.events.pipe(take(1 )).subscribe((event: NavigationStart ) => {
this .saveGridState();
});
}
public ngAfterViewInit ( ) {
this .restoreGridState();
}
public saveGridState ( ) {
const state = this .state.getState() as string ;
window .sessionStorage.setItem('grid1-state' , state);
}
public restoreGridState ( ) {
const state = window .sessionStorage.getItem('grid1-state' );
this .state.setState(state);
}
typescript
열 복원 중
가능한 경우 state 지시문은 상태를 복원할 때 새 열 인스턴스를 만드는 대신 그리드에 이미 존재하는 열을 재사용합니다. 새 인스턴스가 생성되는 유일한 시나리오는 열(또는 열 그룹의 경우 자식)에 속성이 없으므로 field
일치하는 열을 고유하게 식별하고 다시 사용할 수 있는 방법이 없는 경우입니다.
이러한 시나리오의 경우 다음이 limitations
적용됩니다. 이 경우 응용 프로그램 수준의 코드를 사용하여 복잡한 개체를 복원할 수 있습니다. 템플릿 열에 대해 이 작업을 수행하는 방법을 보여 드리겠습니다.
템플릿 참조 변수(아래 예에서는 #activeTemplate
)를 정의하고 columnInit
이벤트에 대한 이벤트 핸들러를 할당합니다.
<igx-grid id ="grid" #grid igxGridState (columnInit )="onColumnInit($event)" >
<igx-column [field ]="'IsActive'" header ="IsActive" >
<ng-template igxCell #activeTemplate let-column let-val ="val" >
<igx-checkbox [checked ]="val" > </igx-checkbox >
</ng-template >
</igx-column >
...
</igx-grid >
html
@ViewChild 또는 @ViewChildren 데코레이터를 사용하여 구성 요소의 템플릿 보기를 쿼리합니다. columnInit
이벤트 핸들러에서 템플릿을 열 bodyTemplate
속성에 할당합니다.
@ViewChild ('activeTemplate' , { static : true }) public activeTemplate: TemplateRef<any >;
public onColumnInit (column: IgxColumnComponent ) {
if (column.field === 'IsActive' ) {
column.bodyTemplate = this .activeTemplate;
column.summaries = MySummary;
column.filters = IgxNumberFilteringOperand.instance();
}
}
typescript
데모
import { Component, OnInit, ViewChild, ViewChildren, QueryList, AfterViewInit } from '@angular/core' ;
import { NavigationStart, Router, RouterLink } from '@angular/router' ;
import { FilteringExpressionsTree, FilteringLogic, GridFeatures, IGridState, IGridStateOptions, IgxGridComponent, IgxGridStateDirective, IgxNumberSummaryOperand, IgxSummaryResult, IgxCheckboxComponent, IgxButtonDirective, IgxIconComponent, IgxPaginatorComponent, IgxGridToolbarComponent, IgxGridToolbarActionsComponent, IgxGridToolbarHidingComponent, IgxGridToolbarPinningComponent, IgxColumnComponent } from 'igniteui-angular' ;
import { take } from 'rxjs/operators' ;
import { employeesData } from './localData' ;
import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scroll.directive' ;
class MySummary {
public operate(data?: any []): IgxSummaryResult[] {
const result = new IgxNumberSummaryOperand().operate(data);
result.push({
key : 'test' ,
label : 'Test' ,
summaryResult : data.filter(rec => rec > 10 && rec < 30 ).length
});
return result;
}
}
@Component ({
selector : 'app-grid' ,
styleUrls : ['./grid-state.component.scss' ],
templateUrl : './grid-state.component.html' ,
imports : [IgxButtonDirective, IgxIconComponent, RouterLink, IgxCheckboxComponent, IgxGridComponent, IgxPreventDocumentScrollDirective, IgxGridStateDirective, IgxPaginatorComponent, IgxGridToolbarComponent, IgxGridToolbarActionsComponent, IgxGridToolbarHidingComponent, IgxGridToolbarPinningComponent, IgxColumnComponent]
})
export class GridSaveStateComponent implements OnInit , AfterViewInit {
@ViewChild (IgxGridStateDirective, { static : true }) public state: IgxGridStateDirective;
@ViewChild (IgxGridComponent, { static : true }) public grid: IgxGridComponent;
@ViewChildren (IgxCheckboxComponent) public checkboxes: QueryList<IgxCheckboxComponent>;
public localData: any [];
public columns: any [];
public gridId = 'grid1' ;
public stateKey = this .gridId + '-state' ;
public gridState: IGridState;
public serialize = true ;
public features: { key : GridFeatures; shortName: string }[] = [
{ key : 'advancedFiltering' , shortName : 'Adv Filt' },
{ key : 'cellSelection' , shortName : 'Cell Sel' },
{ key : 'columns' , shortName : 'Columns' } ,
{ key : 'columnSelection' , shortName : 'Cols Sel' },
{ key : 'expansion' , shortName : 'Expansion' },
{ key : 'filtering' , shortName : 'Filt' },
{ key : 'paging' , shortName : 'Paging' },
{ key : 'rowPinning' , shortName : 'Row Pining' },
{ key : 'rowSelection' , shortName : 'Row Sel' },
{ key : 'sorting' , shortName : 'Sorting' },
{ key : 'groupBy' , shortName : 'GroupBy' }
];
public options: IGridStateOptions = {
cellSelection : true ,
rowSelection : true ,
filtering : true ,
advancedFiltering : true ,
paging : true ,
sorting : true ,
groupBy : true ,
columns : true ,
expansion : true ,
rowPinning : true ,
columnSelection : true
};
public initialColumns: any [] = [
{ field : 'FirstName' , header : 'First Name' , width : '150px' , dataType : 'string' , pinned : true , sortable : true , filterable : true },
{ field : 'LastName' , header : 'Last Name' , width : '150px' , dataType : 'string' , pinned : true , sortable : true , filterable : true },
{ field : 'Country' , header : 'Country' , width : '140px' , dataType : 'string' , groupable : true , sortable : true , filterable : true , resizable : true },
{ field : 'Age' , header : 'Age' , width : '110px' , dataType : 'number' , sortable : true , filterable : true , hasSummary : true , resizable : true , summaries : MySummary},
{ field : 'RegistererDate' , header : 'Registerer Date' , width : '180px' , dataType : 'date' , sortable : true , filterable : true , resizable : true },
{ field : 'IsActive' , header : 'Is Active' , width : '140px' , dataType : 'boolean' , groupable : true , sortable : true , filterable : true }
];
constructor (private router: Router ) {}
public ngOnInit ( ) {
this .localData = employeesData;
this .columns = this .initialColumns;
this .router.events.pipe(take(1 )).subscribe((event: NavigationStart ) => {
this .saveGridState();
});
}
public ngAfterViewInit ( ) {
this .restoreGridState();
}
public saveGridState ( ) {
const state = this .state.getState(this .serialize);
if (typeof state === 'string' ) {
window .localStorage.setItem(this .stateKey, state);
} else {
window .localStorage.setItem(this .stateKey, JSON .stringify(state));
}
}
public restoreGridState ( ) {
const state = window .localStorage.getItem(this .stateKey);
if (state) {
this .state.setState(state);
}
}
public restoreFeature (stateDirective: IgxGridStateDirective, feature: string ) {
const state = this .getFeatureState(this .stateKey, feature);
if (state) {
const featureState = { } as IGridState;
featureState[feature] = state;
stateDirective.setState(featureState);
}
}
public getFeatureState (stateKey: string , feature: string ) {
let state = window .localStorage.getItem(stateKey);
state = state ? JSON .parse(state)[feature] : null ;
return state;
}
public resetGridState ( ) {
const grid: IgxGridComponent = this .grid;
const pagingState = {index : 0 , recordsPerPage : 15 , metadata : { countPages : 3 , countRecords : this .localData.length}};
grid.pagingState = pagingState;
grid.filteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And);
grid.advancedFilteringExpressionsTree = new FilteringExpressionsTree(FilteringLogic.And);
grid.sortingExpressions = [];
grid.groupingExpressions = [];
grid.deselectAllColumns();
grid.deselectAllRows();
grid.clearCellSelection();
}
public onChange (event: any , action: string ) {
if (action === 'toggleAll' ) {
this .checkboxes.forEach(cb => {
cb.checked = event.checked;
});
for (const key of Object .keys(this .options)) {
this .state.options[key] = event.checked;
}
return ;
}
this .state.options[action] = event.checked;
}
public clearStorage ( ) {
window .localStorage.removeItem(this .stateKey);
}
public reloadPage ( ) {
window .location.reload();
}
}
ts コピー <div class ="grid__wrapper" >
<div class ="controls-holder" >
<div class ="switches" >
<button igxButton ="contained" (click )="restoreGridState()" >
<igx-icon class ="btn-icon" > restore</igx-icon >
<span > Restore</span >
</button >
<button igxButton ="contained" (click )="saveGridState()" >
<igx-icon class ="btn-icon" > save</igx-icon >
<span > Save</span >
</button >
<button igxButton ="contained" (click )="resetGridState()" >
<igx-icon class ="btn-icon" > clear</igx-icon >
<span > Reset</span >
</button >
<button igxButton ="contained" [routerLink ]="['../grid-about']" >
<igx-icon class ="btn-icon" > forward</igx-icon >
<span > Leave</span >
</button >
<button igxButton ="contained" (click )="clearStorage()" >
<igx-icon class ="btn-icon" > delete</igx-icon >
<span > Clear</span >
</button >
<button igxButton ="contained" (click )="reloadPage()" >
<igx-icon class ="btn-icon" > refresh</igx-icon >
<span > Reload</span >
</button >
</div >
<div class ="switches" >
<ul >
<li > Clicking the SAVE button or leaving the page <a [routerLink ]="['../grid-about']" > <strong > here</strong > </a > will save grid state to localStorage.</li >
<li > Use the control buttons to SAVE / RESTORE / RESET / DELETE / grid state or LEAVE the page.</li >
<li > Select/Deselect checkboxes to control saving / restoring feature state.</li >
</ul >
</div >
<div class ="switches" >
<div class ="control-item" >
<igx-checkbox [checked ]="true" (change )="onChange($event, 'toggleAll')" > All</igx-checkbox >
</div >
@for (f of features; track f) {
<div class ="control-item" >
<igx-checkbox (change )="onChange($event, f.key)" [checked ]="options[f.key]" >
{{ f.shortName }}
</igx-checkbox >
</div >
}
</div >
</div >
<igx-grid [igxPreventDocumentScroll ]="true" [id ]="gridId" #grid1 [igxGridState ]="options"
width ="98%" height ="530px" [autoGenerate ]="false" [moving ]="true"
[data ]="localData"
[primaryKey ]="'EmployeeID'"
[rowEditable ]="false"
[allowFiltering ]="true"
[filterMode ]="'excelStyleFilter'"
[allowAdvancedFiltering ]="true"
[cellSelection ]="'multiple'"
[rowSelection ]="'none'" >
<igx-paginator > </igx-paginator >
<igx-grid-toolbar >
<igx-grid-toolbar-actions >
<igx-grid-toolbar-hiding > </igx-grid-toolbar-hiding >
<igx-grid-toolbar-pinning > </igx-grid-toolbar-pinning >
</igx-grid-toolbar-actions >
</igx-grid-toolbar >
@for (c of columns; track c) {
<igx-column
[sortable ]="c.sortable"
[editable ]="true"
[hasSummary ]="c.hasSummary"
[filterable ]="c.filterable"
[groupable ]="c.groupable"
[field ]="c.field"
[header ]="c.header"
[dataType ]="c.dataType"
[pinned ]="c.pinned"
[hidden ]="c.hidden" >
</igx-column >
}
</igx-grid >
</div >
html コピー .controls-holder {
display : flex;
justify-content : space-between;
align-items : center;
flex-wrap : wrap;
width : 100% ;
}
.switches {
display : flex;
justify-content : space-between;
justify-content : flex-start;
align-items : center;
flex : 1 0 0% ;
min-width : 100% ;
padding-right : 20px ;
font-size : 0.9rem ;
margin-top : 0 ;
> button {
margin-right : 10px ;
}
}
.control-item {
display : block;
padding : 8px 0px ;
> span {
cursor : pointer;
}
margin-right : 10px ;
}
.grid__wrapper {
margin : 0 16px ;
padding-top : 16px ;
width : 100% ;
igx-grid {
--ig-size: var(--ig-size-medium);
}
}
scss コピー
이 샘플이 마음에 드시나요? 전체 Ignite UI for Angular 툴킷에 액세스하고 몇 분 안에 나만의 앱을 구축해 보세요. 무료로 다운로드하세요.
복원 전략
IgxGridState
기본적으로 원격 작업이나 사용자 정의 차원 전략(자세한 내용은 그리드 원격 작업 샘플 참조)을 유지하지 않습니다(limitations
참조). 이들 중 하나를 복원하는 것은 애플리케이션 수준의 코드를 사용하여 수행할 수 있습니다. IgxGridState
는 그리드 상태가 적용되기 전에 추가로 수정하는 데 사용할 수 있는 stateParsed
라는 이벤트를 노출합니다. 이를 수행하는 방법을 보여드리겠습니다.
사용자 정의 정렬 전략과 사용자 정의 열 및 행 차원 전략을 설정합니다.
<igx-grid #grid
[data ]="data"
[igxGridState ]="options"
[sortStrategy ]="customStrategy"
[height ]="'500px'" >
</igx-grid >
html
@ViewChild (IgxGridStateDirective, { static : true })
public state!: IgxGridStateDirective;
public customStrategy = NoopSortingStrategy.instance();
public options: IGridStateOptions = {...};
typescript
sessionStorage
에서 상태를 복원하고 사용자 정의 전략을 적용하는 것은 다음과 같습니다.
public restoreState ( ) {
const state = window .sessionStorage.getItem('grid-state' );
this .state.stateParsed.pipe(take(1 )).subscribe(parsedState => {
parsedState.sorting.forEach(x => x.strategy = NoopSortingStrategy.instance());
});
this .state.setState(state as string );
}
typescript
import { Component, TemplateRef, ViewChild } from '@angular/core' ;
import { IGridStateOptions, IgxGridStateDirective, IgxGridComponent, NoopSortingStrategy, IgxColumnComponent, IgxButtonDirective, IgxIconComponent, IgxCellTemplateDirective, IgxCellHeaderTemplateDirective, IgxBadgeComponent } from 'igniteui-angular' ;
import { Observable } from 'rxjs' ;
import { take } from 'rxjs/operators' ;
import { FinancialDataService } from '../../services/financial.service' ;
import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scroll.directive' ;
import { AsyncPipe } from '@angular/common' ;
@Component ({
providers : [FinancialDataService],
selector : 'app-grid-state-persistance-sample' ,
styleUrls : ['./grid-state-persistance-sample.component.scss' ],
templateUrl : 'grid-state-persistance-sample.component.html' ,
imports : [IgxButtonDirective, IgxIconComponent, IgxGridComponent, IgxPreventDocumentScrollDirective, IgxGridStateDirective, IgxColumnComponent, IgxCellTemplateDirective, IgxCellHeaderTemplateDirective, IgxBadgeComponent, AsyncPipe]
})
export class GridStatePersistenceSampleComponent {
@ViewChild ('grid' , { static : true })
public grid: IgxGridComponent;
@ViewChild (IgxGridStateDirective, { static : true })
public state!: IgxGridStateDirective;
@ViewChild ('price' , { static : true }) public priceTemplate: TemplateRef<any >;
@ViewChild ('change' , { static : true }) public changeTemplate: TemplateRef<any >;
@ViewChild ('buy' , { static : true }) public buyTemplate: TemplateRef<any >;
@ViewChild ('sell' , { static : true }) public sellTemplate: TemplateRef<any >;
@ViewChild ('spread' , { static : true }) public spreadTemplate: TemplateRef<any >;
@ViewChild ('volume' , { static : true }) public volumeTemplate: TemplateRef<any >;
@ViewChild ('highD' , { static : true }) public highDTemplate: TemplateRef<any >;
@ViewChild ('lowD' , { static : true }) public lowDTemplate: TemplateRef<any >;
@ViewChild ('highY' , { static : true }) public highYTemplate: TemplateRef<any >;
@ViewChild ('lowY' , { static : true }) public lowYTemplate: TemplateRef<any >;
@ViewChild ('startY' , { static : true }) public startYTemplate: TemplateRef<any >;
@ViewChild ('changeOnYear' , { static : true }) public changeOnYearTemplate: TemplateRef<any >;
@ViewChild ('changePercentage' , { static : true }) public changePercentageTemplate: TemplateRef<any >;
public data: Observable<any []>;
public customStrategy = NoopSortingStrategy.instance();
public options: IGridStateOptions = {
rowSelection : true ,
filtering : true ,
sorting : true ,
columnSelection : true
};
constructor (private localService: FinancialDataService ) {
this .localService.getData(100000 );
this .data = this .localService.records;
}
public formatNumber (value: number ) {
return value.toFixed(2 );
}
public formatCurrency (value: number ) {
return '$' + value.toFixed(2 );
}
public saveState ( ) {
const state = this .state.getState() as string ;
window .sessionStorage.setItem('grid-state' , state);
}
public restoreState ( ) {
const state = window .sessionStorage.getItem('grid-state' );
this .state.stateParsed.pipe(take(1 )).subscribe(parsedState => {
parsedState.sorting.forEach(x => x.strategy = this .customStrategy);
});
this .state.setState(state);
}
public clearStorage ( ) {
window .sessionStorage.removeItem('grid-state' );
}
public onColumnInit (column: IgxColumnComponent ) {
if (column.field === 'Price' ) {
column.bodyTemplate = this .priceTemplate;
}
else if (column.field === 'Buy' ) {
column.bodyTemplate = this .buyTemplate;
}
else if (column.field === 'Sell' ) {
column.bodyTemplate = this .sellTemplate;
}
else if (column.field === 'Spread' ) {
column.bodyTemplate = this .spreadTemplate;
}
else if (column.field === 'Volume' ) {
column.bodyTemplate = this .volumeTemplate;
}
else if (column.field === 'High(D)' ) {
column.bodyTemplate = this .highDTemplate;
}
else if (column.field === 'Low(D)' ) {
column.bodyTemplate = this .lowDTemplate;
}
else if (column.field === 'High(Y)' ) {
column.bodyTemplate = this .highYTemplate;
}
else if (column.field === 'Low(Y)' ) {
column.bodyTemplate = this .lowYTemplate;
}
else if (column.field === 'Start(Y)' ) {
column.bodyTemplate = this .startYTemplate;
}
else if (column.field === 'Change On Year(%)' ) {
column.bodyTemplate = this .changeOnYearTemplate;
}
else if (column.field === 'Change(%)' ) {
column.bodyTemplate = this .changeTemplate;
}
else if (column.field === 'Change' ) {
column.bodyTemplate = this .changePercentageTemplate;
}
}
}
ts コピー <div class ="switches" >
<button igxButton ="contained" (click )="restoreState()" >
<igx-icon class ="btn-icon" > restore</igx-icon >
<span > Restore</span >
</button >
<button igxButton ="contained" (click )="saveState()" >
<igx-icon class ="btn-icon" > save</igx-icon >
<span > Save</span >
</button >
<button igxButton ="contained" (click )="clearStorage()" >
<igx-icon class ="btn-icon" > delete</igx-icon >
<span > Clear</span >
</button >
<button igxButton ="contained" (click )="grid.sortStrategy = customStrategy" >
<igx-icon class ="btn-icon" > Set Strategy</igx-icon >
<span > Set NooP custom Sort Strategy</span >
</button >
</div >
<div class ="grid__wrapper" >
<igx-grid [igxPreventDocumentScroll ]="true" [igxGridState ]="options" #grid [data ]="data | async" [height ]="'500px'"
width ="100%" [autoGenerate ]='false' [allowFiltering ]="true" (columnInit )="onColumnInit($event)" >
<igx-column [field ]="'Category'" [sortable ]="true" [width ]="'120px'" > </igx-column >
<igx-column [field ]="'Type'" [sortable ]="true" [width ]="'150px'" [filterable ]="false" > </igx-column >
<igx-column [field ]="'Open Price'" [sortable ]="true" [width ]="'120px'" dataType ="number" >
</igx-column >
<igx-column [field ]="'Price'" [sortable ]="true" [width ]="'120px'" dataType ="number" >
<ng-template igxCell let-column let-val #price >
{{formatCurrency(val)}}
</ng-template >
</igx-column >
<igx-column [field ]="'Change'" [sortable ]="true" [width ]="'120px'" dataType ="number"
[headerClasses ]="'headerAlignSyle'" >
<ng-template igxHeader >
<span > Change</span >
</ng-template >
<ng-template igxCell let-val #change >
<div class ="currency-badge-container" >
@if (val>0) {
<igx-badge type ="success" position ="bottom-right" icon ="arrow_upward"
class ="badge-left" > </igx-badge >
}
@if (val<0) {
<igx-badge type ="error" position ="bottom-right" icon ="arrow_downward"
class ="error badge-left" > </igx-badge >
}
<span class ="cellAlignSyle" [class.up ]="val>0" [class.down ]="val<0" > {{ formatNumber(val) }}</span >
</div >
</ng-template >
</igx-column >
<igx-column [field ]="'Change(%)'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #changePercentage >
{{formatNumber(val)}}
</ng-template >
<ng-template igxHeader >
<span > Change(%)</span >
</ng-template >
<ng-template igxCell let-val >
<span class ="cellAlignSyle" [class.up ]="val>0" [class.down ]="val<0" > {{ formatNumber(val) }}%</span >
</ng-template >
</igx-column >
<igx-column [field ]="'Change On Year(%)'" [sortable ]="true" [width ]="'150px'" dataType ="number" >
<ng-template igxCell let-val #changeOnYear >
<div class ="currency-badge-container" >
@if (val>0) {
<igx-badge type ="success" position ="bottom-right" icon ="arrow_upward"
class ="badge-left" > </igx-badge >
}
@if (val<0) {
<igx-badge type ="error" position ="bottom-right" icon ="arrow_downward"
class ="error badge-left" > </igx-badge >
}
<span class ="cellAlignSyle" [class.up ]="val>0" [class.down ]="val<0" > {{ formatNumber(val) }}%</span >
</div >
</ng-template >
</igx-column >
<igx-column [field ]="'Buy'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #buy >
{{formatCurrency(val)}}
</ng-template >
</igx-column >
<igx-column [field ]="'Sell'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #sell >
{{formatCurrency(val)}}
</ng-template >
</igx-column >
<igx-column [field ]="'Spread'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #spread >
{{formatNumber(val)}}
</ng-template >
</igx-column >
<igx-column [field ]="'Volume'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #volume >
{{formatNumber(val)}}
</ng-template >
</igx-column >
<igx-column [field ]="'High(D)'" [sortable ]="true" [width ]="'130px'" dataType ="number"
[formatter ]="formatCurrency" >
<ng-template igxCell let-column let-val #highD >
{{formatCurrency(val)}}
</ng-template > </igx-column >
<igx-column [field ]="'Low(D)'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #lowD >
{{formatCurrency(val)}}
</ng-template >
</igx-column >
<igx-column [field ]="'High(Y)'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #highY >
{{formatCurrency(val)}}
</ng-template >
</igx-column >
<igx-column [field ]="'Low(Y)'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #lowY >
{{formatCurrency(val)}}
</ng-template >
</igx-column >
<igx-column [field ]="'Start(Y)'" [sortable ]="true" [width ]="'130px'" dataType ="number" >
<ng-template igxCell let-column let-val #startY >
{{formatCurrency(val)}}
</ng-template >
</igx-column >
</igx-grid >
<br />
</div >
html コピー .cellAlignSyle {
text-align : right;
float :right ;
}
.cellAlignSyle > span {
float :right ;
}
.up {
color : green;
}
.down {
color : red;
}
.headerAlignSyle {
text-align : right !important ;
}
.grid__wrapper {
margin : 0 auto;
padding : 16px ;
}
.currency-badge-container {
width : 80px ;
float : right;
}
.badge-left {
float : left;
}
.switches {
display : flex;
justify-content : flex-start;
align-items : center;
flex : 1 0 0% ;
min-width : 100% ;
padding-right : 20px ;
font-size : 0.9rem ;
margin : 10px ;
>button {
margin-right : 10px ;
}
}
scss コピー
제한 사항
API 참조
추가 리소스