おはようございます、朝6時です・・早いです、そして寒いです。今日はだいぶ冷えるとのことで、冬らしくなってきました。
前回からのあらすじ
前回の終わりにて
コンポーネントからビューのデータバインディングはここまでとして(入門なのでサクッと)、
次はビューからコンポーネントのデータバインディング、イベントバインディングを見てみましょう。
ということで、
前回のコンポーネントからビューへのデータバインディングを見ましたが、今日はビューからコンポーネントへデータを渡すイベントバインディングを見てみます。
早速サンプルアプリを見てみましょ。
イベントバインディング
基本
<h1>Counter</h1>
<p>This is a simple example of an Angular component.</p>
<p>Current count: <strong>{{ currentCount }}</strong></p>
<button (click)="incrementCounter()">Increment</button>
ここ→<button (click)="incrementCounter()">Increment</button>
ボタンをクリックしたときにincrementCounter()
を呼ぶ。この部分がイベントバインディングになります。
イベントの種類
他にも下記のようなイベントも使えます(もっとあるけど抜粋)
イベント名 | イベント |
---|---|
click | クリックされたとき |
dblclick | ダブルクリックされたとき |
focus | 要素がフォーカスされたとき |
keydown | キーを押したとき |
input | 入力内容が変更されたとき |
select | セレクトされたとき |
reset | リセットされたとき |
submit | サブミットされたとき |
イベントバインディングに関しては後ほど、さらに詳しくカバーしていく予定ですが、一旦基本はこの辺りで。
次は双方向バインディングを見てデータバインディング編を終わりとします。
双方向バインディング
双方向バインディングは字のごとく、コンポーネント側からもビュー側からもデータをバインディングしあう方法です。
VSのサンプルアプリには事例がないので、新しくビューとコンポーネントを作成します。
全く実用性がありませんが、好きな本の名前を入力して、出力するプログラムを例として書いてみます。
まずはビューから
<h1>Book</h1>
<p>Type in name of your favorite book</p>
<form>
<label for="name">名前: </label>
<input id="name" name="name" type="text" [(ngModel)]="book.name"/>
</form>
<hr/>
<p>
You like {{book.name}}
</p>
そしてコンポーネント
import { Component } from '@angular/core';
@Component({
selector: 'app-books-component',
templateUrl: './books.component.html'
})
export class BooksComponent {
book = { name: 'Bleach 第一巻'} ;
}
ここで表記があるように
<element name="name" [(ngModel)]="property"/>
が基本構文になっています。このようにコンポーネントで定義してクラスプロパティーを要素にバインディングして利用していくことができます。
新しいページを追加
このページを表示するのに、新しく作ったコンポーネントを登録し、ルーティングにも登録する必要があるので、app.module.tsも更新します。ルーティングに関しては後程詳しくカバーします。今は一旦読み通してください。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { CounterComponent } from './counter/counter.component';
import { FetchDataComponent } from './fetch-data/fetch-data.component';
import { BooksComponent } from './books/books.component'; //追記
@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
HomeComponent,
CounterComponent,
FetchDataComponent,
BooksComponent //追記
],
imports: [
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
HttpClientModule,
FormsModule,
RouterModule.forRoot([
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'counter', component: CounterComponent },
{ path: 'fetch-data', component: FetchDataComponent },
{ path: 'books', component: BooksComponent} //追記
])
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
左側のナビゲーションメニューにリンクも追記します。アイコンは面倒なので一旦コピペで。
<div class='main-nav'>
<div class='navbar navbar-inverse'>
<div class='navbar-header'>
<button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse' [attr.aria-expanded]='isExpanded' (click)='toggle()'>
<span class='sr-only'>Toggle navigation</span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
</button>
<a class='navbar-brand' [routerLink]='["/"]'>NodejsWebAppAngularTutorial1</a>
</div>
<div class='clearfix'></div>
<div class='navbar-collapse collapse' [ngClass]='{ "in": isExpanded }'>
<ul class='nav navbar-nav'>
<li [routerLinkActive]='["link-active"]' [routerLinkActiveOptions]='{ exact: true }'>
<a [routerLink]='["/"]' (click)='collapse()'>
<span class='glyphicon glyphicon-home'></span> Home
</a>
</li>
<li [routerLinkActive]='["link-active"]'>
<a [routerLink]='["/counter"]' (click)='collapse()'>
<span class='glyphicon glyphicon-education'></span> Counter
</a>
</li>
<li [routerLinkActive]='["link-active"]'>
<a [routerLink]='["/fetch-data"]' (click)='collapse()'>
<span class='glyphicon glyphicon-th-list'></span> Fetch data
</a>
</li>
<!--追記-->
<li [routerLinkActive]='["link-active"]'>
<a [routerLink]='["/books"]' (click)='collapse()'>
<span class='glyphicon glyphicon-th-list'></span> Favorite Book
</a>
</li>
</ul>
</div>
</div>
</div>
アプリケーション実行、見てみる
まずはデフォルトのタイトルが表示されていることを確認します。
テキストボックスの内容を更新すると、同時に下のテキストも更新されることが確認できました。
次、非同期通信
データバインディングの基本はここで終了です。次回はもう少し実用性のあるアプリケーションを作りたいと思います。入力した値に対して外部のAPIから情報を取得するというアプリケーションを例に非同期通信を見てみたいと思います。
Angular入門としては他にも先にカバーするべき要素はあると思いましたが、まずは実用的な例から入って、後程他のコンポーネント、パイプ、サービス、ルーティング、テストなどなどカバーしていきます。