Angular 複数行レイアウト
複数行レイアウトは、igxGridComponent
のレンダリング機能を拡張します。この機能により、単一のデータレコードを複数の表示行に分割することができます。
Angular 複数行レイアウトの例
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 { GridMultiRowLayoutComponent } from "./grid/grid-multi-row-layout/grid-multi-row-layout.component";
import { IgxGridModule } from "igniteui-angular";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
GridMultiRowLayoutComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxGridModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component, ViewEncapsulation } from '@angular/core';
import { DefaultSortingStrategy, SortingDirection } from 'igniteui-angular';
import { DATA } from '../../data/customers';
@Component({
encapsulation: ViewEncapsulation.None,
selector: 'app-grid-multi-row-layout-sample',
styleUrls: ['./grid-multi-row-layout.component.scss'],
templateUrl: './grid-multi-row-layout.component.html'
})
export class GridMultiRowLayoutComponent {
public sourceData = DATA;
public group = [
{
dir: SortingDirection.Asc,
fieldName: 'Country',
ignoreCase: false,
strategy: DefaultSortingStrategy.instance()
}
];
public sort = [
{
dir: SortingDirection.Desc,
fieldName: 'CompanyName',
ignoreCase: true
}
];
}
ts
<div class="wrapper">
<igx-grid [igxPreventDocumentScroll]="true" #grid
[width]="'100%'"
height="720px"
[data]="sourceData"
[autoGenerate]="false"
[groupingExpressions]="group"
[sortingExpressions]="sort"
[allowFiltering]="true"
[displayDensity]="'cosy'">
<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-layout [pinned]="true" [header]="'ID'">
<igx-column [rowStart]="1" [colStart]="1" [rowEnd]="3" field="ID" [filterable]="false" [width]="'150px'"></igx-column>
</igx-column-layout>
<igx-column-layout [pinned]="true" [header]="'Contact Details'">
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="3" field="CompanyName" [header]="'Company Name'" [sortable]="true" [width]="'350px'"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" [colEnd]="2" field="ContactName" [header]="'Contact Name'" [groupable]="true"></igx-column>
<igx-column [rowEnd]="3" [rowStart]="2" [colStart]="2" [colEnd]="3" field="ContactTitle" [header]="'Contact Title'" [groupable]="true"></igx-column>
</igx-column-layout>
<igx-column-layout [header]="'Address Details'">
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="3" field="Country" [groupable]="true" [filterable]="false" [width]="'220px'"></igx-column>
<igx-column [rowStart]="1" [colStart]="3" [colEnd]="5" field="Region" [groupable]="true" [filterable]="false" [width]="'220px'"></igx-column>
<igx-column [rowStart]="1" [colStart]="5" [colEnd]="7" field="PostalCode" [header]="'Postal Code'" [groupable]="true" [filterable]="false" [width]="'220px'"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" [colEnd]="4" field="City" [groupable]="true" [filterable]="false"></igx-column>
<igx-column [rowStart]="2" [colStart]="4" [colEnd]="7" field="Address" [filterable]="false"></igx-column>
</igx-column-layout>
<igx-column-layout [header]="'Phone Details'">
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="2" field="Phone" [filterable]="false" [width]="'220px'"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" [colEnd]="2" field="Fax" [filterable]="false"></igx-column>
</igx-column-layout>
</igx-grid>
</div>
html
.wrapper {
padding: 16px;
}
scss
このサンプルが気に入りましたか? 完全な Ignite UI for Angularツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
複数行レイアウトの宣言は、igx-column-layout
コンポーネントによって実現されます。各 igx-column-layout
コンポーネントは、単一または複数の igx-column
コンポーネントを含むブロックと見なします。一部のグリッド機能はブロック レベルで機能します (下記の「機能の統合」セクション参照)。たとえば、仮想化ではブロックを使用して仮想チャンクを決定します。そのため、レイアウトで許容される場合は、パフォーマンスを向上させるために列を更に igx-column-layout
ブロックに分割します。複数行のレイアウトを設定するときは、これらのブロックの外側に列がなく、IgxColumnGroupComponent
を使用しないでください。複数行レイアウトは、グリッド レイアウト仕様上に実装されており、その要件に準拠する必要があります。
IgxColumnComponent
は各セルの位置と範囲を決めるために 4 つの @Input
プロパティを公開しています。
colStart
- フィールドの開始位置となる列インデックス。このプロパティは必須です。
rowStart
- フィールドの開始位置となる行インデックス。このプロパティは必須です。
colEnd
- 現在のフィールドが終了する位置の列インデックス。colStart と colEnd の間の列数によって、そのフィールドまでの列の幅が決まります。このプロパティはオプションです。設定されていない場合は、デフォルトで 1 に設定されます。
rowEnd
- 現在のフィールドが終了する行インデックス。rowStart と rowEnd の間の行数によって、そのフィールドにまたがる行数が決まります。このプロパティはオプションです。設定されていない場合は、デフォルトで rowStart + 1
に設定されます。
<igx-column-layout>
<igx-column [rowStart]="1" [colStart]="1" [rowEnd]="3" field="ID"></igx-column>
</igx-column-layout>
<igx-column-layout>
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="3" field="CompanyName"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" [colEnd]="2" field="ContactName"></igx-column>
<igx-column [rowStart]="2" [colStart]="2" [colEnd]="3" field="ContactTitle"></igx-column>
</igx-column-layout>
<igx-column-layout>
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="3" field="Country"></igx-column>
<igx-column [rowStart]="1" [colStart]="3" [colEnd]="5" field="Region"></igx-column>
<igx-column [rowStart]="1" [colStart]="5" [colEnd]="7" field="PostalCode"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" [colEnd]="4" field="City"></igx-column>
<igx-column [rowStart]="2" [colStart]="4" [colEnd]="7" field="Address"></igx-column>
</igx-column-layout>
<igx-column-layout>
<igx-column [rowStart]="1" [colStart]="1" field="Phone"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" field="Fax"></igx-column>
</igx-column-layout>
html
上記の設定の結果は、以下のスクリーンショットで確認できます。
rowStart
プロパティと colStart
プロパティは、それぞれの igx-column
に対してigx-column-layout
に設定する必要があります。igxColumnLayout
コンポーネントはレイアウトが正しいかどうかを検証しておらず、それについてエラーや警告を投げていません。開発者は、レイアウトの宣言が正しく完全であることを確認する必要があります。誤った配置、オーバーラップ、ブラウザの不整合などが発生し、レイアウトが壊れる可能性があります。
機能の統合
複数行レイアウトのレンダリング方法は全く異なるため、列固定や列非表示など一部の列機能は igx-column-layout
コンポーネントでのみ機能します。その他の機能ソートとグループ化などは、igx-column
コンポーネントで同じように機能します。
- フィルタリング - Excel スタイルのフィルタリングのみがサポートされています。
filterMode
を FilterMode.quickFilter
に明示的に設定しても効果はありません。
- ページング - 表示行ではなくレコードで機能します。
- グループ化 -
hideGroupedColumns
オプションは、複数行レイアウトでは効果がありません。グループ化された列は常に表示されます。
以下の機能は現在サポートされません。
- 列移動
- 複数列ヘッダー
- Excel へエクスポート
- 集計
キーボード ナビゲーション
複数行レイアウトを持つ IgxGridComponent は、ビルトインのキーボード ナビゲーションを提供します。
水平ナビゲーション
- 左矢印または右矢印は、現在行内の左右に隣接するセルに移動します。定義されている列レイアウトの影響を受けません。現在のセルが複数の行にまたがる場合は、他の隣接するセルへ移動した場合を除き、左矢印と右矢印は、同じ
rowStart
で左右の最初のセルに移動します。ナビゲーションはナビゲーション開始セルを格納し、可能であれば同じ rowStart
を持つセルに移動します。
- Ctrl + 左矢印 (HOME) または Ctrl + 右矢印 (END) - 行の先頭または末尾に移動し、ナビゲーション開始セルに従ってセルを選択します。
垂直ナビゲーション
- 上矢印 または 下矢印 - 開始位置に対して上下のセルに移動し、行の影響は受けません。現在のセルが複数の列にまたがる場合は、次のアクティブ セルがナビゲーション開始セルに従って選択されます。
- Ctrl + 上矢印またはCtrl + Down - 最初の行または最後の行の同じ列に移動してフォーカスを適用します。
- Ctrl + Home または Ctrl + End - 最初の行に移動して最初のセルに移動するか、最後のセルに移動します。最後のセルに移動してフォーカスを合わせます。
複数の行または列にわたるセルを介したナビゲーションは、ナビゲーション開始セルに従って行われ、反対方向のキーを使用して開始セルに戻ることができます。グループ行を移動するときにも同じ方法が使用されます。
選択と複数セル選択はレイアウトで使用できます。つまり、セルがアクティブになると、そのレイアウトが選択されます。ドラッグ選択などの複数選択のすべての機能も適用可能であり、セルごとではなくレイアウトごとに機能します。
カスタム キーボード ナビゲーション
グリッドでは、特定のキーが押されたときのデフォルトのナビゲーション動作をカスタマイズできます。隣りのセル
または下のセル
へ移動するような操作は、キーボード ナビゲーション API を使用して簡単に処理できます。
gridKeydown
が公開されます。イベントは IGridKeydownEventArgs
を発生します。このイベントは、キーボードで上記のキー組み合わせを介してのみ使用できます。他のすべてのキー操作では、keydown
イベント (keydown)="onKeydown($event)"
を使用できます。
navigateTo
- このメソッドを使用すると、提供された rowindex
と visibleColumnIndex
に基づいて位置に移動できます。
以下のデモでは、Excel と同じように、Enter と Shift + Enter キーを使って追加のナビゲーションを使用します。
デモ
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 { GridMRLCustomNavigationComponent } from "./grid/grid-mrl-custom-navigation/grid-mrl-custom-navigation.component";
import { IgxGridModule } from "igniteui-angular";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
GridMRLCustomNavigationComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxGridModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component, ViewChild, ViewEncapsulation } from '@angular/core';
import { IgxGridComponent } from 'igniteui-angular';
import { DATA } from '../../data/company-data';
@Component({
encapsulation: ViewEncapsulation.None,
selector: 'app-grid-mrl-custom-navigation-sample',
styleUrls: ['./grid-mrl-custom-navigation.component.scss'],
templateUrl: './grid-mrl-custom-navigation.component.html'
})
export class GridMRLCustomNavigationComponent {
@ViewChild(IgxGridComponent, { read: IgxGridComponent, static : true })
public grid: IgxGridComponent;
public sourceData = DATA;
public customNavigation(args) {
const target = args.target;
if (args.event.key.toLowerCase() === 'enter') {
args.event.preventDefault();
args.cancel = true;
const rowIndex = target.row.index === undefined ? target.index : target.row.index;
this.grid.navigateTo(args.event.shiftKey ? rowIndex - 1 : rowIndex + 1, target.column.visibleIndex,
(obj) => {
obj.target.activate();
});
}
}
}
ts
<div class="wrapper">
<igx-grid [igxPreventDocumentScroll]="true" #grid
[width]="'100%'"
height="570px"
[data]="sourceData"
[autoGenerate]="false"
[displayDensity]="'cosy'" (gridKeydown)="customNavigation($event)" >
<igx-column-layout [header]="'Company'">
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="3" field="company" header='Company'></igx-column>
<igx-column [rowStart]="2" [colStart]="1"field="country" header='Country'></igx-column>
<igx-column [rowStart]="2" [colStart]="2" field="city" header='City'></igx-column>
<igx-column [rowStart]="3" [colStart]="1" [colEnd]="3" field="address" header='Address'></igx-column>
</igx-column-layout>
<igx-column-layout [header]="'Sales'">
<igx-column [rowStart]="1" [rowEnd]='3' [colStart]="1" [colEnd]="3" field="sales_lifetimeSales" header='Lifetime Sales'></igx-column>
<igx-column [rowStart]="3" [colStart]="1" field="sales_quarterlySales" header='Quarterly'></igx-column>
<igx-column [rowStart]="3" [colStart]="2" field="sales_yearlySales" header='Yearly'></igx-column>
</igx-column-layout>
<igx-column-layout [header]="'Market Potential'">
<igx-column [rowStart]="1" [rowEnd]='4' [colStart]="1" field="sales_marketPotential" header='Market Potential'></igx-column>
</igx-column-layout>
<igx-column-layout [header]="'Assets'">
<igx-column [rowStart]="1" [colStart]="1" field="assets_cash" header='Assets Cash'></igx-column>
<igx-column [rowStart]="1" [colStart]="2" [colEnd]="4" field="assets_accRec" header='Accounts Receivable'></igx-column>
<igx-column [rowStart]="2" [rowEnd]='4' [colStart]="1" [colEnd]="4" field="assets_books" header='Assets Books'></igx-column>
</igx-column-layout>
</igx-grid>
</div>
html
.wrapper {
padding: 16px;
}
scss
レイアウトの構成
列レイアウトを構成するときに、適切な colStart
および colEnd
、または rowStart
および rowEnd
を計算して設定するのが難しい場合があります。特に 1 つのレイアウトに多数の列がある場合などですが、適用時のプレビューを簡単に確認するためにコンフィギュレーターを使用できます。以下の操作が可能です。
- 設定全体の行数を設定します。すべてのレイアウトは同じ行数である必要があります。
レイアウトの追加
チップをクリックするか、レイアウトチップを左右にドラッグしてソートします。
- 各レイアウトに特定の設定を列数と幅に合わせて設定します。設定は現在選択されているレイアウトを参照します。
- レイアウト プレビューで列セルのサイズを変更して、より多くの列/行にまたがるようにしたり、
削除
ボタンを使用して列セルを消去したりできます。
- プレビューで列チップをドラッグして列を設定します。
列の追加
チップを使用して新しい列を追加/削除します。
NgForOf
を使用してテンプレート内で使用および解析できる JSON 表現または igxGrid 内に配置できるように構成全体のテンプレート出力を取得します。
デフォルトでは、前のサンプルと同じ列を設定していますが、目的の設定に合わせて消去して設定することもできます。
スタイル設定
igxGrid を使用すると、Ignite UI for Angular テーマ ライブラリ
でスタイルを設定できます。grid-theme
は、グリッドのすべての機能をカスタマイズできるさまざまなプロパティを公開します。
以下は、グリッドの複数行レイアウト スタイルをカスタマイズする手順です。
グローバル テーマのインポート
複数行レイアウト機能のカスタマイズは、すべてのスタイリング機能とミックスインが配置されている index
ファイルをインポートする必要があります。
@use "igniteui-angular/theming" as *;
scss
カスタム テーマの定義
次に、grid-theme
を拡張し、必要に応じて機能レイアウトをカスタマイズするために必要なパラメーターを受け取る新しいテーマを作成します。
$custom-theme: grid-theme(
$cell-active-border-color: #ffcd0f,
$cell-selected-background: #6f6f6f,
$row-hover-background: #fde069,
$row-selected-background: #8d8d8d,
$header-background: #494949,
$header-text-color: #fff,
$sorted-header-icon-color: #ffcd0f,
$sortable-header-icon-hover-color: #e9bd0d
);
scss
上記のようにカラーの値をハードコーディングする代わりに、palette
および color
関数を使用してカラーに関してより高い柔軟性を実現することができます。使い方の詳細についてはパレット
のトピックをご覧ください。
カスタム テーマの適用
テーマを適用する最も簡単な方法は、グローバル スタイル ファイルに sass
@include
ステートメントを使用することです。
@include css-vars($custom-theme);
scss
カスタム テーマが特定のコンポーネントのみに影響するように、定義したすべてのスタイルをグローバル スタイル ファイルからカスタム コンポーネントのスタイルファイルに移動できます (index
ファイルのインポートを含む)。
このように、Angular の ViewEncapsulation により、スタイルはカスタム コンポーネントにのみ適用されます。
デモ
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 { GridMultiRowLayoutStylingComponent } from "./grid/grid-multi-row-layout-styling/grid-multi-row-layout-styling.component";
import { IgxGridModule } from "igniteui-angular";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
GridMultiRowLayoutStylingComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxGridModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component, ViewEncapsulation } from '@angular/core';
import { DefaultSortingStrategy, SortingDirection } from 'igniteui-angular';
import { DATA } from '../../data/customers';
@Component({
encapsulation: ViewEncapsulation.None,
selector: 'app-grid-multi-row-layout-styling-sample',
styleUrls: ['./grid-multi-row-layout-styling.component.scss'],
templateUrl: './grid-multi-row-layout-styling.component.html'
})
export class GridMultiRowLayoutStylingComponent {
public sourceData = DATA;
public group = [
{
dir: SortingDirection.Asc,
fieldName: 'Country',
ignoreCase: false,
strategy: DefaultSortingStrategy.instance()
}
];
public sort = [
{
dir: SortingDirection.Desc,
fieldName: 'CompanyName',
ignoreCase: true
}
];
}
ts
<div class="wrapper">
<igx-grid [igxPreventDocumentScroll]="true" #grid
[width]="'100%'"
height="720px"
[data]="sourceData"
[autoGenerate]="false"
[sortingExpressions]="sort"
[displayDensity]="'cosy'">
<igx-column-layout [header]="'ID'">
<igx-column [rowStart]="1" [colStart]="1" [rowEnd]="3" field="ID" [filterable]="false"></igx-column>
</igx-column-layout>
<igx-column-layout [header]="'Contact Details'">
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="3" field="CompanyName" [header]="'Company Name'" [sortable]="true"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" [colEnd]="2" field="ContactName" [header]="'Contact Name'"></igx-column>
<igx-column [rowEnd]="3" [rowStart]="2" [colStart]="2" [colEnd]="3" field="ContactTitle" [header]="'Contact Title'"></igx-column>
</igx-column-layout>
<igx-column-layout [header]="'Address Details'">
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="3" field="Country"></igx-column>
<igx-column [rowStart]="1" [colStart]="3" [colEnd]="5" field="Region"></igx-column>
<igx-column [rowStart]="1" [colStart]="5" [colEnd]="7" field="PostalCode" [header]="'Postal Code'" [filterable]="false"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" [colEnd]="4" field="City"></igx-column>
<igx-column [rowStart]="2" [colStart]="4" [colEnd]="7" field="Address"></igx-column>
</igx-column-layout>
<igx-column-layout [header]="'Phone Details'">
<igx-column [rowStart]="1" [colStart]="1" [colEnd]="2" field="Phone"></igx-column>
<igx-column [rowStart]="2" [colStart]="1" [colEnd]="2" field="Fax"></igx-column>
</igx-column-layout>
</igx-grid>
</div>
html
@use '../../../variables' as *;
.wrapper {
padding: 16px;
}
$custom-theme: grid-theme(
$cell-active-border-color: #ffcd0f,
$cell-selected-background: #6f6f6f,
$row-hover-background: #fde069,
$row-selected-background: #8d8d8d,
$header-background: #494949,
$header-text-color: #fff,
$sorted-header-icon-color: #ffcd0f,
$sortable-header-icon-hover-color: #e9bd0d
);
:host ::ng-deep {
@include css-vars($custom-theme);
}
scss
このサンプルは、Change Theme
(テーマの変更) から選択したグローバル テーマに影響を受けません。
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。