3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ignite UI for AngularAdvent Calendar 2018

Day 7

igx-grid の列定義の方法さまざま

Last updated at Posted at 2018-12-07

2018/12/07(Fri) 時点の情報に基づいています

Ignite UI for Angular の igx-grid を表示させるのに最低限必要な情報が2つあります。

  1. データ
  2. 列定義

データは以下のような配列を用意します。

[
  { id: 1, column1: 1, column2: 2, ... },
  { id: 2, column1: 1, column2: 2, ... },
  ...
]

上記のデータに対して、

  • id に対する定義
  • column1 に対する定義
  • column2 に対する定義
  • ・・・

とそれぞれどのように列を表示するかを定義する必要があります。列定義の方法にはいくつかあるので、それぞれ紹介していきます。

1. データから自動生成

まずは一番簡単な方法から。列定義を自動生成する方法です。
前回の記事 でも igx-grid を表示するのにこの方法を使いましたが、[autoGenerate]="true" を指定するだけです。

xxx.component.html
  <!-- 
    こんな感じのデータを用意
    data = [
      { id: 1, column1: 1, column2: 2, ... },
      { id: 2, column1: 1, column2: 2, ... },
    ]
   このデータをバインドして [autoGenerate]="true" とすると列定義が自動生成されます
  -->
  <igx-grid [data]="data" [autoGenerate]="true"></igx-grid>
  • Pros
    • データを用意するだけでよいです。
  • Cons
    • igx-grid の機能が限られます。
      • 使える機能:フィルタリング、ページング、行選択、列非表示、列固定、エクスポート
      • 使えない機能:編集、列ソート、列移動、列リサイズ、列サマリー、複数列ヘッダー
    • 列のカスタマイズができません。例えば幅の指定など、自動生成のため全てが一律で同じに決まってしまいます。また、自分で列定義を記述すればテンプレートを使ってセル内の構造を自由にカスタマイズすることもできますが、これも自動生成してしまうとできなくなります。
  • 使い所
    • デモを作るときに最小限の労力でさくっと表示したいときに使います。
    • Web API からデータを引っ張ってきて、取得データが想定通りかデバッグしたいときに使ったりします。

2. igx-column を使った方法

  1. の Cons を解消する方法です。
    igx-column というコンポーネントを使って、列定義を書いていきます。
xxx.component.html
  <!-- 自分で列定義を書きます。その場合は autoGenerate を削除するか [autoGenerate]="false" とします -->
  <igx-grid [data]="data">
    <igx-column [field]="'id'" [header]="'ID'" [dataType]="'number'"></igx-column>
    <igx-column [field]="'column1'" [header]="'Column 1'" [dataType]="'string'" [width]="200"></igx-column>
    <igx-column [field]="'column2'" [header]="'Column 2'" [dataType]="'string'" [width]="300"></igx-column>
    ...
  </igx-grid>

列定義の基本プロパティは以下の3つです。受け付ける値は全て string型 であることに注意してください。

  • [field]="'<列のキー>'"
  • [header]="'<列の名前>'"
  • [dataType]="'<列の型>'" ※ string/number/boolean/date のみをサポートします

上記3つに加えて [width]="200" などとして個別に幅を指定しています。他にも APIリファレンス を見ると、編集、列ソート、列移動、列リサイズ、列サマリーなどの機能を有効にするためのプロパティがあります。

  • Pros
      1. の Cons を解消します。
  • Cons
    • 列数が多くなってくると辛くなります。
  • 使い所
    • 表示データが自明で、列数がそれほど多くない場合に使います。
    • 往々にして列数は多くなりがちなので、実はあまり使い所がないかもしれません。

3. igx-columnngFor を使った方法

  1. の Cons を解消する方法です。
    igx-columnngFor と組み合わせて使うことができ、以下のような実装になります。これなら列数がいくつあっても対応できます。
xxx.component.html
  <igx-grid [data]="data">
    <igx-column *ngFor="let column of columns"
                [field]="column.field"
                [header]="column.header"
                [dataType]="column.dataType"
                [width]="column.width">
    </igx-column>
  </igx-grid>

2 の方法とは違い、igx-columnngFor で扱うために columns というコレクションを用意する必要が出てきます。以下は Object.entries() を使ってデータから key-value のペアを取得し columns を生成するサンプルです。

xxx.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-xxx',
  templateUrl: './xxx.component.html',
  styleUrls: ['./xxx.component.scss']
})
export class XxxComponent implements OnInit {
  data: any[];

  columns: any[];

  ngOnInit(): void {
    // データの生成
    this.data = Array.from({ length: 1000 }).map((_, i) => {
      const num = i + 1;
      const item = { id: num };
      Array.from({ length: 99 }).forEach((__, j) => {
        let value;
        // string
        if (j % 4 === 0) value = `item${num}`;
        // number
        if (j % 4 === 1) value = num;
        // boolean
        if (j % 4 === 2) value = num % 2 === 0;
        // date
        if (j % 4 === 3) value = new Date(new Date().setDate(num));
        item[`column${j + 1}`] = value;
      });
      return item;
    });

    // 列定義の生成
    this.columns = Object.entries(this.data[0]).map(([key, value], index) => {
      const dataType = Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
      return {
        field: key,
        header: key.toUpperCase(),
        dataType,
        width: 100 + (index % 5) * 50
      };
    });
  }
}

TypeScript 側で columns のコレクションを作るためにいろいろやらなければなりませんが、非常に柔軟に列を定義することができるようになります。条件によって、A列は編集可、B列は編集不可、といった制御も可能です。

  • Pros
    • 列数が増えても大丈夫です。
    • かなり柔軟に列定義を行うことができます。
  • Cons
    • 列定義のコレクションを生成するのが複雑になりがちです。
  • 使い所
    • いろいろな状況で使え、最も実用的です。

4. 2 + 3 の複合技

2 と 3 は組み合わせることができます。
例えば、『必ず表示する列が2列あり、それ以外の列は可変としたい』といった要件があった場合に使えます。

xxx.component.html
  <igx-grid [data]="data">
    <!-- 必ず表示するので 2 の方法で定義 -->
    <igx-column [field]="'foo'" [header]="'FOO'" [dataType]="'string'"></igx-column>
    <igx-column [field]="'bar'" [header]="'BAR'" [dataType]="'string'"></igx-column>

    <!-- 列数は状況によって増減するので 3 の方法で定義 -->
    <igx-column *ngFor="let column of columns"
                [field]="column.field"
                [header]="column.header"
                [dataType]="column.dataType"
                [editable]="column.editable">
    </igx-column>
  </igx-grid>

個人的な結論

  • 『3. igx-columnngFor を使った方法』最も実用的です。
  • 『1. データから自動生成』 は、デモやデバッグ目的で使うことが多いです。ただし、使えないというわけではありません。データを表示するだけの要件にはマッチします。
  • 『2. igx-column を使った方法』 単品では実はあまり出番がないかもしれません。『4. 2 + 3 の複合技』 で紹介したように、3と組み合わせることでより効果を発揮します。

Ignite UI for Angular が気になった方はこちら

デモサイトで様々なサンプルを試すことができるので色々試してみてください!
https://jp.infragistics.com/products/ignite-ui-angular/angular/components/grid_virtualization.html

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?