Dart2×AngularDart5 チュートリアル Part2. Master/Detail

この記事は「Webアプリ入門しようよ! in AngularDart」の続きです。

目次
Part1:The Hero Editor
Part2:Master/Detail ←イマココ!
Part3:Multiple Components/Services
Part4:Routing
Part5:HTTP

参考

Part1は終わったようですね。

え?終わってない?
そんなあなたにはこちら↓を差し上げましょう。
Part1終了時点のソースコード

それでは続きから!Hurry!

Heroリストを表示!

  1. ちょっとリファクタリング!

    • lib/hero.dartlib/src/hero.dartへ移動!

    • app_component.dartを修正!

          import 'package:angular_forms/angular_forms.dart';
          // ↓パスを変更!
          import 'src/hero.dart';
      

    ブラウザを更新して確認!
    同じように表示されたらOK!

    ネクストッ!

  2. Heroリストのモックsrc/mock_heroes.dartを作る!

        import 'hero.dart';
    
        final mockHeroes = <Hero>[
            Hero(11, 'Mr. Nice'),
            Hero(12, 'Narco'),
            Hero(13, 'Bombasto'),
            Hero(14, 'Celeritas'),
            Hero(15, 'Magneta'),
            Hero(16, 'RubberMan'),
            Hero(17, 'Dynama'),
            Hero(18, 'Dr IQ'),
            Hero(19, 'Magma'),
            Hero(20, 'Tornado')
        ];
    

    将来的にはWebサービスからHeroリストを取得するけど、一旦仮で作っておくよ!

  3. lib/app_component.dartを修正!

    import 'src/hero.dart';
    // ↓追加!
    import 'src/mock_heroes.dart';
    
    @Component(
      selector: 'my-app',
      templateUrl: 'app_component.html',
      // ↓テンプレートでngForを使うためにcoreDirectiveを追加!
      directives: [coreDirectives, formDirectives],
    )
    class AppComponent {
      final title = 'Tour of Heroes';
      var hero = Hero(1, 'Windstorm');
      // ↓heroからHeroのリストであるheroesに変更!
      List<Hero> heroes = mockHeroes;
    }
    
  4. lib/app_component.htmlを修正!

    <!-- ↓タイトル以外を変更! -->
    <h1>{{title}}</h1>
    <h2>Heroes</h2>
    <ul class="heroes">
        <!-- heroes内の要素数分繰り返す! -->
        <li *ngFor="let hero of heroes">
            <!-- heroを表示する! -->
            <span class="badge">{{hero.id}}</span> {{hero.name}}
        </li>
    </ul>
    

    *ngForについて

    • *<li>要素が[マスターテンプレート]であることを明示するものらしい!
    • ngForは、<li>要素内の要素を繰り返すために使うよ!
    • ここでは、heroesmockHeroes)の10人のHeroを1人づつheroに取り出して、なくなるまで繰り返す!

ブラウザを更新して確認!
dart_5

ネクストッ!

Heroリストの見た目を変更!

  1. lib/app_component.cssを作成!

    .selected {
      background-color: #CFD8DC !important;
      color: white;
    }
    .heroes {
      margin: 0 0 2em 0;
      list-style-type: none;
      padding: 0;
      width: 15em;
    }
    .heroes li {
      cursor: pointer;
      position: relative;
      left: 0;
      background-color: #EEE;
      margin: .5em;
      padding: .3em 0;
      height: 1.6em;
      border-radius: 4px;
    }
    .heroes li.selected:hover {
      color: white;
    }
    .heroes li:hover {
      color: #607D8B;
      background-color: #EEE;
      left: .1em;
    }
    .heroes .text {
      position: relative;
      top: -3px;
    }
    .heroes .badge {
      display: inline-block;
      font-size: small;
      color: white;
      padding: 0.8em 0.7em 0 0.7em;
      background-color: #607D8B;
      line-height: 1em;
      position: relative;
      left: -1px;
      top: -4px;
      height: 1.8em;
      margin-right: .8em;
      border-radius: 4px 0 0 4px;
    }
    
  2. lib/app_component.dartを修正!

    @Component(
      selector: 'my-app',
      // ↓スタイルの定義を追加!
      styleUrls: ['app_component.css'],
      templateUrl: 'app_component.html',
      directives: [coreDirectives, formDirectives],
    )
    

これらのスタイルはAppComponentにのみ適用され、外側のHTMLには影響しないよ!

ブラウザを更新して確認!
dart_6

ネクストッ!

クリックで詳細を表示!

  1. lib/app_component.htmlを修正!

    <h1>{{title}}</h1>
    <!-- ↓Heroの詳細表示を追加! -->
    <!-- ↓heroを選択している時だけ表示する! -->
    <div *ngIf="selected != null">
        <h2>{{selected.name}}</h2>
        <div><label>id: </label>{{selected.id}}</div>
        <div>
            <label>name: </label>
            <input [(ngModel)]="selected.name" placeholder="name">
        </div>
    </div>
    <h2>Heroes</h2>
    <ul class="heroes">
        <!-- ↓heroとselectedが一致したときのみCSSクラス「selected」を適用! -->
        <!-- ↓li要素をクリックした時、onSelect関数を呼び出してHeroの選択を反映! -->
        <li *ngFor="let hero of heroes" [class.selected]="hero === selected" (click)="onSelect(hero)">
            <!-- heroを表示する! -->
            <span class="badge">{{hero.id}}</span> {{hero.name}}
        </li>
    </ul>
    

    ngIfについて
    ngIfngForと似たようなもので、条件に一致したときだけその要素を表示するよ!
    *をつけるのもngForと同じ!

    (click)について
    (click)<li>要素をクリックしたときに、定義したAppComponentのメソッドを呼び出すぞ!
    ここではonSelect()だね!

    ===について
    ===演算子は、左右のオブジェクトが同じだったらTrue、違ったらFalseになるよ!
    ここでは、取り出したheroが選択したHero(selected)と同じだったら、<li>要素にCSSクラスselectedを適用するという動作になる!

  2. lib/app_component.dartを修正!

    class AppComponent {
      final title = 'Tour of Heroes';
      List<Hero> heroes = mockHeroes;
      Hero selected;
    
      // ↓実装!
      void onSelect(Hero hero) => selected = hero;
    }
    

    ブラウザを更新して確認!
    dart_7

    =>について
    =>は関数定義の糖衣構文!下の2つは同じ動作になるよ!

        void onSelect(Hero hero) => selected = hero;
    
        void onSelect(Hero hero) {
          selected = hero;
        }
    

    気になったら試してみよう!

ひと休み

ここまでいかがだったでしょうか。

あなたがクールにコーディングしている姿が目に浮かびます。

説明は相変わらず雑ですが、その調子でいきましょう!

ネクストッ! → Part3:Multiple Components/Services