[Microsoft] 2. リストを表示する - Angularチュートリアル Tour of Heroes を Blazor で再実装する

# 選択肢リストを表示する

[前回](https://qiita.com/sengoku/items/81c58a37aeef5899df9f)からの続きです。
ヒーローの一覧を表示できるようにします。
一覧からヒーローを選択すると、詳細が表示されるようにします。

----


# ヒーローたちのモックを作成する

ヒーローのリストを返すクラスを作成しました。

```cs:Model/MockHeroes.cs
using System.Collections.Generic;

namespace BlazorTourOfHeroes.Model
{
    public class MockHeroes
    {
        public static List<Hero> Create() => new List<Hero> {
            new Hero { Id= 11, Name= "Dr Nice", },
            new Hero { Id= 12, Name= "Narco" },
            new Hero { Id= 13, Name= "Bombasto" },
            new Hero { Id= 14, Name= "Celeritas" },
            new Hero { Id= 15, Name= "Magneta" },
            new Hero { Id= 16, Name= "RubberMan" },
            new Hero { Id= 17, Name= "Dynama" },
            new Hero { Id= 18, Name= "Dr IQ" },
            new Hero { Id= 19, Name= "Magma" },
            new Hero { Id= 20, Name= "Tornado" },
        };
    }
}
```


# ヒーローたちを表示する

Heroesコンポーネントに`heroes`変数を追加します。

```razor:Shared/Heroes.razor
    private List<Hero> heroes = MockHeroes.Create();
```

## ヒーローたちを一覧する

`foreach`でヒーローたちをイテレートします。

```razor:Shared/Heroes.razor
<h2>My Heroes</h2>
<ul class="heroes">
    @foreach (var hero in heroes)
    {
        <li><span class="badge">@hero.Id</span> @hero.Name </li>    
    }
</ul>
```

## ヒーローたちにスタイルをあてる

全体共通のスタイルシートを編集します。

[Anguarのチュートリアル](https://angular.io/tutorial/toh-pt2#final-code-review)からコピペしました。


# こんなんできました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/8d43d664-3278-febb-356e-d87a26466149.png)


# 詳細表示を作成する

一覧をクリックしたら、詳細を表示するようにします。

## クリックイベントをバインドする

`<li>` タグにクリックイベントを追加します。

引数を渡したいので、ラムダにします。

```razor:Shared/Heroes.razor
<li @onclick="@(_ => OnSelect(hero))">
```

## クリックイベントハンドラを作成する

選択されたヒーローを格納する変数とイベントハンドラを作成します。

```razor:Shared/Heroes.razor
    private Hero selectedHero;

    private void OnSelect(Hero hero)
    {
        selectedHero = hero;
    }
```


## 詳細表示部分を追加する

選択されたヒーローを表示するようにします。

```razor:Shared/Heroes.razor
<h2>@selectedHero.Name.ToUpper() Details</h2>
<div><span>Id: </span>@selectedHero.Id</div>
<div>
  <label>Name:
    <input @bind="selectedHero.Name" placeholder="name"/>
  </label>
</div>
```

ここで実行すると、ブラウザのコンソールにぬるぽが出力されました。

```
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
  at BlazorTourOfHeroes.Shared.Heroes.BuildRenderTree (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) <0x2c456d0 + 0x00246> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0 (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) <0x2b30640 + 0x0001a> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch (Microsoft.AspNetCore.Components.Rendering.RenderBatchBuilder batchBuilder, Microsoft.AspNetCore.Components.RenderFragment renderFragment) <0x2b2ff78 + 0x00054> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch (Microsoft.AspNetCore.Components.Rendering.RenderQueueEntry renderQueueEntry) <0x2b2da88 + 0x0004c> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue () <0x2b2d1c8 + 0x00092> in <filename unknown>:0 blazor.webassembly.js:formatted:2093
```

### ぬるぽを修正


`selectedHero`がnullのときは、詳細部分を出力しないようにします。

```razor:Shared/Heroes.razor
@if (selectedHero != null)
{
    <h2>@selectedHero.Name.ToUpper() Details</h2>
    <div><span>Id: </span>@selectedHero.Id</div>
    <div>
    <label>Name:
        <input @bind="selectedHero.Name" placeholder="name"/>
    </label>
    </div>
}
```

## 選択中のヒーローにスタイルをあてる

`class`属性の中でRazor構文を使います。

```razor:Shared/Heroes.razor
        <li @onclick="@(_ => OnSelect(hero))"
            class="@(selectedHero == hero ? "selected" : "")"
            ><span class="badge">@hero.Id</span> @hero.Name
        </li>    
```

# こんなんできました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/c53e3b20-5ba1-4eeb-f7fd-1d51a633d361.png)