LoginSignup
2
3

More than 3 years have passed since last update.

[Angular] 入門 - 基本編 2 - データバインディング 2

Last updated at Posted at 2018-12-10

おはようございます、朝6時です・・早いです、そして寒いです。今日はだいぶ冷えるとのことで、冬らしくなってきました。

前回からのあらすじ

前回の終わりにて

コンポーネントからビューのデータバインディングはここまでとして(入門なのでサクッと)、
次はビューからコンポーネントのデータバインディング、イベントバインディングを見てみましょう。

ということで、
前回のコンポーネントからビューへのデータバインディングを見ましたが、今日はビューからコンポーネントへデータを渡すイベントバインディングを見てみます。

早速サンプルアプリを見てみましょ。

イベントバインディング

基本

/ClientApp/src/app/counter.component.html
<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のサンプルアプリには事例がないので、新しくビューとコンポーネントを作成します。

全く実用性がありませんが、好きな本の名前を入力して、出力するプログラムを例として書いてみます。

まずはビューから

/ClientApp/src/app/books.component.html
<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>

そしてコンポーネント

/ClientApp/src/books.component.ts
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も更新します。ルーティングに関しては後程詳しくカバーします。今は一旦読み通してください。

/ClientApp/src/app/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 { }

左側のナビゲーションメニューにリンクも追記します。アイコンは面倒なので一旦コピペで。

/ClientApp/src/app/nav-menu.component.html
<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>

アプリケーション実行、見てみる

まずはデフォルトのタイトルが表示されていることを確認します。

image.png

テキストボックスの内容を更新すると、同時に下のテキストも更新されることが確認できました。

image.png

次、非同期通信

データバインディングの基本はここで終了です。次回はもう少し実用性のあるアプリケーションを作りたいと思います。入力した値に対して外部のAPIから情報を取得するというアプリケーションを例に非同期通信を見てみたいと思います。

Angular入門としては他にも先にカバーするべき要素はあると思いましたが、まずは実用的な例から入って、後程他のコンポーネント、パイプ、サービス、ルーティング、テストなどなどカバーしていきます。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3