ふらぱいく

備忘録。いい加減つける

Angular 入門してみる3

選択した社員の詳細と名前入力欄とstyleの適用,また「ngModel」による双方向バインディングの実装。

1.選択した社員の詳細と名前入力欄の実装

templateの編集

前回の社員の詳細templateを,選択した社員に適用したいので,選択(クリック)された場合にクラスを付与。
(click)はeventで,onSelectメソッド(後ほど記述)を着火。[class.selected]は,trueの場合にliタグのclassをセットする。
selected-member-detail属性のmemberをselectedMemberにしておく。

    <h1>{{title}}</h1>
    
    <ul class="members">
    <li *ngFor="let member of member" 
        (click)="onSelect(member)" 
        [class.selected]="member === selectedMember">
      <span class="badge">{{member.id}}</span>{{member.name}}
    </li>
    </ul>
    
    <div class="selected-member-detail">
      <div>
        id: {{selectedMember.id}}
      </div>
      <div>
        name: {{selectedMember.name}}
      </div>
    </div>
Componentに追加

templateに基づき記述。
export class AppComponent {
title = '自社社員名簿';
selectedMember: Member; // 選択された社員のプロパティ
member = MEMBERS;

// 画面で社員が選択された時着火されるonSelect()によって,selectedMemberにmemberを代入
onSelect(member: Member): void {
this.selectedMember = member;
}
}

styleの適用

templateやselecterと同じ箇所に,配列で記述

    .selected {
      background-color: #CFD8DC !important;
      color: white;
    }
    .members {
      margin: 0 0 2em 0;
      list-style-type: none;
      padding: 0;
      width: 15em;
    }
    .members li {
      cursor: pointer;
      position: relative;
      left: 0;
      background-color: #EEE;
      margin: .5em;
      padding: .3em 0;
      height: 1.6em;
      border-radius: 4px;
    }
    .members li.selected:hover {
      background-color: #BBD8DC !important;
      color: white;
    }
    .members li:hover {
      color: #607D8B;
      background-color: #DDD;
      left: .1em;
    }
    .members .text {
      position: relative;
      top: -3px;
    }
    .members .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;
    }

実行結果
クリックした社員の詳細が出力された。
f:id:noinoi_monstS4l:20190529213758p:plain

2.入力フォームを作成

双方向バインディングによる動的な動作を実装。

双方向バインディング

モデルのプロパティが更新されると,UIも更新され,反対にUIが更新されると,変更内容がモデルにも反映されること。
Angularで「フォーム」の入力値をコンポーネントと同期するには?(双方向バインディング):Angular TIPS - @IT
使用するには,参照するModuleにFormsModuleを追加。

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent }  from './app.component';
// tslint:disable-next-line:quotemark
import {FormsModule} from "@angular/forms";  // 追加

@NgModule({
  imports: [BrowserModule, FormsModule],  // 追加
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

templateに以下を追加。
属性に*ngIfを追加。「selectedMemberが存在する場合」詳細が有効になる。ここではクリックした場合。
また,名前をバインディングしたいので,inputタグにngModelを追加。WebStormのインテリジェンスつよい。

    <div *ngIf="selectedMember">
      <div>
        id: {{selectedMember.id}}
      </div>
      <div>
        name: {{selectedMember.name}}
      </div>
      <div>
        <input type="text" [(ngModel)]="selectedMember.name">
      </div>
    </div>

実行結果。*ngIfにより,最初の非選択画面では詳細は表示されない。
f:id:noinoi_monstS4l:20190529215259p:plain

バインディングも動作。
f:id:noinoi_monstS4l:20190529215325p:plain

次回はコンポーネントの分割からLifeSycleHookまで?
以上。まだいける。