Hierarchical Grid の状態保持
igxGridState ディレクティブによって開発者がグリッドの状態を簡単に保存および復元できます。IgxGridState
ディレクティブがグリッドに適用されると、getState
および setState
メソッドが公開され、開発者はこれを使用して、あらゆるシナリオで状態の永続化を実現できます。
サポートされている機能
IgxGridState
ディレクティブは、以下の機能の状態の保存および復元をサポートします。
行アイランド
ソート
フィルタリング
高度なフィルタリング
ページング
セル選択
行の選択
列の選択
行のピン固定
展開
列
複数列ヘッダー
列の順序
IColumnState
インターフェイスによって定義される列プロパティ。
列テンプレートおよび関数はアプリケーション レベルのコードを使用して復元されます。列の復元 セクションを参照してください。
使用方法
getState
- このメソッドは、シリアル化された JSON 文字列でグリッド状態を返します。これは、開発者がそれを取得して任意のデータストレージ (データベース、クラウド、ブラウザーの localStorage など) に保存できます。このメソッドは最初のオプションのパラメーター serialize
を受け取り、getState
が IGridState
オブジェクトを返すか、シリアル化された JSON 文字列を返すかを決定します。
開発者は、機能名、または機能名を 2 番目の引数として持つ配列を渡すことにより、特定の機能の状態のみを取得することを選択できます。
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-hierarchical-grid [igxGridState ]="options" > </igx-hierarchical-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
プロパティがなく、一致する列を一意に識別して再利用する方法がない場合です。
このようなシナリオでは、以下の制限
が課せられます。これらの復元は、アプリケーション レベルのコードで実現できます。テンプレート化された列でこれを行う方法を示します。
テンプレート参照変数 (以下の例では #activeTemplate
) を定義し、columnInit
イベントにイベント ハンドラーを割り当てます。
<igx-hierarchical-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-hierarchical-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
子グリッドの復元
子グリッドの状態の保存/復元は、rowIslands
プロパティによって制御され、デフォルトで有効に設定されています。IgxGridState
は、ルート グリッドと階層のすべての子グリッドの両方の機能を保存/復元するために同じオプションを使用します。たとえば、以下のオプションを渡す場合:
<igx-grid [igxGridState ]="options" > </igx-grid >
html
getState
API は、selection
と sorting
を除くすべてのグリッド (ルート グリッドと子グリッド) 機能の状態を返します。開発者が後ですべてのグリッドのfiltering
状態のみを復元するには、以下を使用します。
this .state.setState(state, ['filtering' , 'rowIslands' ]);
typescript
デモ
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import { IgxHierarchicalGridModule } from "igniteui-angular" ;
import { HGridSaveStateComponent } from "./hierarchical-grid/hierarchical-grid-save-state/hGrid-state.component" ;
import { HGridAboutComponent } from "./hierarchical-grid/hierarchical-grid-save-state/about.component" ;
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive" ;
import {
Router,
RouterModule
} from "@angular/router" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
HGridSaveStateComponent,
HGridAboutComponent
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxHierarchicalGridModule,
RouterModule.forRoot([{component : HGridAboutComponent, path : 'hGrid-state-about' },{component : HGridSaveStateComponent, path : 'hGrid-state' },{ path : '' , redirectTo : '/hGrid-state' , pathMatch : 'full' }])
],
providers : [],
entryComponents : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component, OnInit, ViewChild, ViewChildren, QueryList, AfterViewInit } from '@angular/core' ;
import { NavigationStart, Router } from '@angular/router' ;
import { GridFeatures,
IGridState, IGridStateOptions, IgxGridStateDirective,
IgxHierarchicalGridComponent, IgxNumberSummaryOperand,
IgxSummaryResult, IgxCheckboxComponent} from 'igniteui-angular' ;
import { take } from 'rxjs/operators' ;
import { SINGERS } from '../../data/singersData' ;
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-hgrid' ,
styleUrls : ['./hGrid-state.component.scss' ],
templateUrl : './hGrid-state.component.html'
})
export class HGridSaveStateComponent implements OnInit , AfterViewInit {
@ViewChild (IgxGridStateDirective, { static : true }) public state: IgxGridStateDirective;
@ViewChild ('hierarchicalGrid' , { static : true }) public hGrid: IgxHierarchicalGridComponent;
@ViewChildren (IgxCheckboxComponent) public checkboxes: QueryList<IgxCheckboxComponent>;
public localData: any [];
public columns: any [];
public gridId = 'hGrid1' ;
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 : 'rowIslands' , shortName : 'Row Islands' }
];
public options: IGridStateOptions = {
cellSelection : true ,
rowSelection : true ,
filtering : true ,
advancedFiltering : true ,
paging : true ,
sorting : true ,
columns : true ,
expansion : true ,
rowPinning : true ,
columnSelection : true
};
constructor (private router: Router ) {
this .localData = SINGERS;
}
public ngOnInit ( ) {
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 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();
}
public formatter = (a ) => a;
}
ts コピー <div class ="grid__wrapper" >
<div class ="controls-holder" >
<div class ="switches" >
<button igxButton ="raised" (click )="restoreGridState()" >
<igx-icon class ="btn-icon" > restore</igx-icon >
<span > Restore</span >
</button >
<button igxButton ="raised" (click )="saveGridState()" >
<igx-icon class ="btn-icon" > save</igx-icon >
<span > Save</span >
</button >
<button igxButton ="raised" [routerLink ]="['../hGrid-state-about']" >
<igx-icon class ="btn-icon" > forward</igx-icon >
<span > Leave</span >
</button >
<button igxButton ="raised" (click )="clearStorage()" >
<igx-icon class ="btn-icon" > delete</igx-icon >
<span > Clear</span >
</button >
<button igxButton ="raised" (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 ]="['../hGrid-state-about']" > <strong > here</strong > </a > will save grid state to localStorage.</li >
<li > Use the control buttons to SAVE / RESTORE / 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 >
<div class ="control-item" *ngFor ="let f of features" >
<igx-checkbox (change )="onChange($event, f.key)" [checked ]="options[f.key]" >
{{ f.shortName }}
</igx-checkbox >
</div >
</div >
</div >
<igx-hierarchical-grid [igxPreventDocumentScroll ]="true" #hierarchicalGrid class ="hgrid" igxGridState
[data ]="localData" [height ]="'500px'" [width ]="'98%'" [rowHeight ]="'65px'"
[primaryKey ]="'Photo'"
[autoGenerate ]="false"
[columnSelection ]="'multiple'"
displayDensity ="cosy"
[cellSelection ]="'multiple'" >
<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 >
<igx-column field ="Artist" [sortable ]="true" > </igx-column >
<igx-column field ="Photo" [editable ]="false" [sortable ]="true" >
<ng-template igxCell let-cell ="cell" >
<div class ="cell__inner_2" >
<img [src ]="cell.value" class ="photo" />
</div >
</ng-template >
</igx-column >
<igx-column field ="Debut" dataType ="number" [formatter ]="formatter" [sortable ]="true" > </igx-column >
<igx-column field ="GrammyNominations" header ="Grammy Nominations" dataType ="number" [sortable ]="true" > </igx-column >
<igx-column field ="GrammyAwards" header ="Grammy Awards" dataType ="number" [sortable ]="true" > </igx-column >
<igx-row-island [height ]="null" [key ]="'Albums'"
[autoGenerate ]="false"
[primaryKey ]="'Album'"
rowSelection ='multiple'
[allowFiltering ]='true'
[columnSelection ]="'multiple'"
[cellSelection ]="'multiple'" >
<igx-column field ="Album" [sortable ]="true" > </igx-column >
<igx-column field ="LaunchDate" header ="Launch Date" [dataType ]="'date'" [sortable ]="true" > </igx-column >
<igx-column field ="BillboardReview" header ="Billboard Review" [sortable ]="true" > </igx-column >
<igx-column field ="USBillboard200" header ="US Billboard 200" [sortable ]="true" > </igx-column >
<igx-row-island [height ]="null" [key ]="'Songs'"
[autoGenerate ]="false"
[primaryKey ]="'Number'"
rowSelection ='multiple'
[allowFiltering ]='true'
[columnSelection ]="'multiple'"
[cellSelection ]="'multiple'" >
<igx-column field ="Number" header ="No." [sortable ]="true" > </igx-column >
<igx-column field ="Title" [sortable ]="true" > </igx-column >
<igx-column field ="Released" dataType ="date" [sortable ]="true" > </igx-column >
<igx-column field ="Genre" > </igx-column >
</igx-row-island >
</igx-row-island >
<igx-row-island [height ]="null" [key ]="'Tours'"
[autoGenerate ]="false"
[primaryKey ]="'Tour'"
rowSelection ='multiple'
[allowFiltering ]='true'
[columnSelection ]="'multiple'"
[cellSelection ]="'multiple'" >
<igx-column field ="Tour" [sortable ]="true" > </igx-column >
<igx-column field ="StartedOn" header ="Started on" [sortable ]="true" > </igx-column >
<igx-column field ="Location" [sortable ]="true" > </igx-column >
<igx-column field ="Headliner" [sortable ]="true" > </igx-column >
</igx-row-island >
</igx-hierarchical-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 : 10px ;
width : 100% ;
}
scss コピー
このサンプルが気に入りましたか? 完全な Ignite UI for Angularツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
制限
パラメーターなしで setState
API を使用してすべてのグリッド機能を一度に復元する場合、ルート グリッドの列プロパティがデフォルトにリセットされる場合があります。その場合は、後で列または列の選択機能を復元してください。
state.setState(gridState);
state.setState(gridState.columns);
state.setState(gridState.columnSelection);
typescript
API リファレンス
その他のリソース