Ionicでアコーディオンメニューリストをつくる。

# 概要
Ionic Advent Calendar 2019
6日目の記事です。

渋谷で [エンタメマッチングアプリ pato](https://pato.today/) を開発している内田です。
Ionicでリストを表示しつつ、クリックしたらアコーディオンメニューが表示されるサンプルです。
僕がめちゃめちゃ悩んでたのを先輩がサクッと解決してくれたので、メモとして残します。雑です。
作るものは、こんな感じのやつです。
![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227205/4fadf9da-387b-430e-8bea-ca57eb8effb3.gif)
# リストってどうやって作るん？
Ionicでは、`<ion-list>`タグで作成可能です！
[公式サイト](https://ionicframework.com/docs/api/list)で詳しく説明されています。
公式サイトのリストを使っていじっていきます！

```html:hello-ionic.html
<ion-list>
  <ion-item>
    <ion-label>Pokémon Yellow</ion-label>
  </ion-item>
  <ion-item>
    <ion-label>Mega Man X</ion-label>
  </ion-item>
  <ion-item>
    <ion-label>The Legend of Zelda</ion-label>
  </ion-item>
  <ion-item>
    <ion-label>Pac-Man</ion-label>
  </ion-item>
  <ion-item>
    <ion-label>Super Mario World</ion-label>
  </ion-item>
</ion-list>
```

# 動的なリストの作成
`*ngFor`を使って、リストに繰り返し処理を加えます。
まずは、対象のリストの配列を作りましょう。

```typescript:hello-ionic.ts
import { Component } from '@angular/core';

@Component({
  selector: 'page-hello-ionic',
  templateUrl: 'hello-ionic.html'
})
export class HelloIonicPage {
  gameTitles = [
   { lavel: "Pokémon Yellow" },
   { lavel: "Mega Man X" },
   { lavel: "The Legend of Zelda" },
   { lavel: "Pac-Man" },
   { lavel: "Super Mario World" }
  ];
  constructor() {
    this.gameTitles;
  }
}
```

`*ngFor`の使い方は[こちら](https://angular.jp/guide/displaying-data#ngfor--%E3%81%A7%E9%85%8D%E5%88%97%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B)

```html:hello-ionic.html
<ion-list>
  <ion-item *ngFor="let game of gameTitles">
    <ion-label>{{ game.lavel }}</ion-label>
  </ion-item>
</ion-list>
```

# アコーディオン可能な処理を加える
今回はリストのPokémon Yellowに最初のポケモンたちを表示させましょう！
...としたかったんですが、Pokémon Yellow == ポケットモンスター ピカチュウ
なので、最初に選べるポケモンは強制的にピカチュウです。
なんか面白くないので、Pokémon Redってことにします！

```typescript:sample-list.ts
import { Component } from '@angular/core';

@Component({
  selector: 'page-hello-ionic',
  templateUrl: 'hello-ionic.html'
})
export class HelloIonicPage {
  pokemons = ["zenigame", "hitokage", "fushigidane"];
  gameTitles = [
   { lavel: "Pokémon Red" }, 
   { lavel: "Mega Man X" },
   { lavel: "The Legend of Zelda" },
   { lavel: "Pac-Man" },
   { lavel: "Super Mario World" }
  ];
  constructor() {
    this.gameTitles;
    this.pokemons;
  }
}
```

`ng-container`で囲みましょう。
 選択したtitleにアコーディオンを表示させるため、`*ngFor`を`<ng-container>`に移動させます。

```html:hello-ionic.html
<ion-list>
  <ng-container *ngFor="let game of gameTitles; let idx = index">
    <ion-item>
      <ion-label>{{ game.lavel }}</ion-label>
    </ion-item>
   </ng-container>
</ion-list>
```

選択された`idx`を取得するために、`selectGameTitle()`を作ります。
sample-list.tsに以下のように追加します。

```typescript:hello-ionic.ts
import { Component } from '@angular/core';

@Component({
  selector: 'page-hello-ionic',
  templateUrl: 'hello-ionic.html'
})
export class HelloIonicPage {
  pokemons = ["zenigame", "hitokage", "fushigidane"];
  selectTitle: number = 0;
  gameTitles = [
   { lavel: "Pokémon Red" }, 
   { lavel: "Mega Man X" },
   { lavel: "The Legend of Zelda" },
   { lavel: "Pac-Man" },
   { lavel: "Super Mario World" }
  ];
  constructor() {
    this.gameTitles;
    this.pokemons;
    this.selectTitle;
  }
  selectGameTitle(idx): void{
    this.selectTitle = idx;
  }
}
```

`ion-item`の下に表示させたいアコーディオンを加えましょう。
Pokémon Redのpokemonsだけ表示させたいので、
`*ngIf`を使いましょう！
また、`ionSelect`を使うことで、指定されたradioボタンの`idx`を取得できます。

```html:hello-ionic.html
<ion-list>
  <ng-container *ngFor="let game of gameTitles; let idx = index">
     <ion-item>
       <ion-label>{{ game.lavel }}</ion-label>
       <ion-radio name="games" (ionSelect)="selectGameTitle(idx)" ></ion-radio>
     </ion-item>
     <div *ngIf="selectTitle == 0 && game.lavel == 'Pokémon Red'">
       <div *ngFor="let pokemon of pokemons">
         <p>{{ pokemon }}</p>
       </div>
     </div>
  </ng-container>
</ion-list>
```
`*ngIf`の使い方は[こちら](https://angular.jp/guide/displaying-data#ngif%E3%81%AB%E3%82%88%E3%82%8B%E6%9D%A1%E4%BB%B6%E4%BB%98%E3%81%8D%E8%A1%A8%E7%A4%BA)

結果は以下のようになります。
![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227205/4fadf9da-387b-430e-8bea-ca57eb8effb3.gif)

以上で、アコーディオンメニューの完成です。