2018年2月4日日曜日

Angular5 TODO リスト作成

Angular5 で簡易な TODO リストを作成する実装例を紹介します。

環境準備

node.js 及び npm のインストール

Angular によるアプリケーション開発を行うにあたり、これら機能を利用しますので、それぞれインストールします。インストール後、バージョンを確認します。

バージョン確認
node -v
npm -v

Angular インストール

次のコマンドで Angular CLI をインストールします。
npm install @angular/cli -g


Angular バージョ確認
ng -v


Angular CLI プロジェクトの作成、及びアプリケーションの起動

次のコマンドで Angular CLI プロジェクトを作成します。
ng new todoApp

作成したアプリケーションフォルダに移動
cd todoApp

アプリケーション起動
ng serve -o

→ ブラウザが起動してアプリケーションを表示


ここまでで開発の準備になります。ここから Angular CLI プロジェクトに実装を加えていきます。

機能実装

機能の実装は 1 ~ 15 のステップになります。

タスク数の表示

1.変数 taskText, taskCount を宣言する。

app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  //1
  taskText:string;
  taskCount: number;
}


2.インターポレーションでテンプレートに taskCount を表示する。

app.component.html
<div style="text-align:center">
  <h1>
      タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>
</div>


3.FormsModule をインポートする。

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';//3

import { AppComponent } from './app.component';


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


タスクの追加機能

コンポーネントが初期化されるタイミングで発生するライフサイクルイベントをハンドルし、コンポーネントで利用する変数の初期化を行います。

4. OnInit をインポートする。
5. AppComponent に OnInit を実装する。
6. 変数 tasks を宣言する。
7. ngOnInit イベント内で taskText を空文字で、taskCount の値を tasks の要素数で初期化する。
8. addTask メソッドを追加する。

app.component.ts
import { Component, OnInit/*4*/ } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit/*5*/ {
  title = 'app';

  //1
  taskCount: number;
  tasks = [];//6
  
  ngOnInit(){
    //7
    this.taskText = "";
    this.taskCount = this.tasks.length;
  }

  //8
  addTask(taskNameValue: string){
    this.tasks.push(taskNameValue);
    this.taskCount = this.tasks.length;
  }
}

続いてテンプレート(HTML)側にも、データのバインドなどを実装していきます。


9. input(text) を実装し、taskName という名前をつける。
10. input(text) の value に ngModel を利用して taskText の値を双方向バインドする。
11. input(button) に click イベントを実装する。

app.component.html
<div style="text-align:center">
  <h1>
    タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>

  <input #taskName type="text" [(ngModel)]="taskText"><!-- 9, 10 -->

  <input type="button" value="タスク追加" (click)="addTask(taskName.value)"><!-- 11 -->
</div>

ここまでで、input(button) をクリックすると、コンポーネント側で tasks 配列の要素が追加され、テンプレート側でバインドしている taskCount の値も増えていくことを確認することができます。

タスクのリスト表示

続けて、追加したタスクをリスト形式で表示するための実装を加えていきます。


12. tasks 配列の各要素をリスト表示する。

app.component.html
<div style="text-align:center">
  <h1>
    タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>

  <input #taskName type="text" [(ngModel)]="taskText"><!-- 9, 10 -->

  <input type="button" value="タスク追加" (click)="addTask(taskName.value)"><!-- 11 -->
</div>

<ul>
  <!-- 12 -->
  <li *ngFor="let task of tasks">
    {{ task }}
  </li>
</ul>


13. タスクリストの位置調整

app.component.css
ul {
    position: relative;
    left: 40%;
}

ここまでで、ボタンクリックでタスクが追加していくようになります。

タスクの削除

タスクの追加ができたら、タスクの削除もできるようにします。タスクの削除は、タスク(li 要素)をクリックした時に行います。

14. input(button) に click イベントを登録する。

app.component.html
<div style="text-align:center">
  <h1>
    タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>

  <input #taskName type="text" [(ngModel)]="taskText"><!-- 9, 10 -->

  <input type="button" value="タスク追加" (click)="addTask(taskName.value)"><!-- 11 -->
</div>

<ul>
  <!-- 12 -->
  <li *ngFor="let task of tasks; let idx = index;" (click)="removeTask(idx)"><!-- 14 -->
    {{ task }}
  </li>
</ul>

コンポーネント側で、タスクを削除するための removeTask イベントハンドラを実装します。

15. app.component.ts
//15
removeTask(idx:number){
  this.tasks.splice(idx, 1);
}

以上で、簡単ではありますが、Angular を利用した TO DO リストの作成ができました。


全ソースコード

各ファイルのソースコードは次のようになっています。

app.component.ts
import { Component, OnInit/*4*/ } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit/*5*/ {
  title = 'app';

  //1
  taskText:string;
  taskCount: number;

  tasks = [];//6
  
  ngOnInit(){
    //7
    this.taskText = "";
    this.taskCount = this.tasks.length;
  }

  //8
  addTask(taskNameValue: string){
    this.tasks.push(taskNameValue);
    this.taskCount = this.tasks.length;
    this.taskText = "";
  }
  //15
  removeTask(idx:number){
    this.tasks.splice(idx, 1);
  }
}

app.component.html
<div style="text-align:center">
  <h1>
    タスク数 = {{ taskCount }}<!-- 2 -->
  </h1>

  <input #taskName type="text" [(ngModel)]="taskText"><!-- 9, 10 -->

  <input type="button" value="タスク追加" (click)="addTask(taskName.value)"><!-- 11 -->
</div>

<ul>
  <!-- 12 -->
  <li *ngFor="let task of tasks; let idx = index;" (click)="removeTask(idx)"><!-- 14 -->
    {{ task }}
  </li>
</ul>

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';//3

import { AppComponent } from './app.component';


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

app.component.css
ul {
    position: relative;
    left: 40%;
}
以上になります。


Angular に関連するトピックは次のページにまとめてあります。

Angular 機能紹介一覧
https://kainobi2.blogspot.com/2019/02/angular.html

超簡易 Python サーバー作成方法

Python3 で簡易ウェブサーバーを作成する手順をメモしておきます。

1.フォルダレイアウト
C:\py
  - cgi-bin
    - index.py
    - index.tpl

2.実装
index.py
print('Content-type: text/html; charset=UTF-8\r\n')
fopen = open("cgi-bin/index.tpl", encoding="utf-8")
lines = fopen.read()
fopen.close()
print(lines)

index.tpl
<html>
    <head>
        <title>aaa</title>
    </head>
    <body>
        aaabbbccc
    </body>
</html>

3.コマンド
C:\py> python -m http.server --cgi 8000


4.ブラウザでアクセス
http://localhost:8000/cgi-bin/index.py