iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
1
Modern Web

Angular 深入淺出三十天系列 第 6

[Angular 深入淺出三十天] Day 05 - Angular 小學堂(一)

「接下來要說明的是...喂!睡著了阿你?!」專心講解的我瞄了 Wayne 一眼,才發現這小子居然已經睡倒流口水了?!

「對不起!!因為一直在講解沒有實作,一不小心就睡著了...。」Wayne 被我拍了一下醒了過來,擦了擦嘴邊的口水後,不好意思地說道。

「好吧!既然如此,我們寫些小功能來提振一下精神好了!」又好氣又好笑的我見狀只好決定先做個小功能來暖暖身,順便為後面的講解鋪個路。

「Finally!!事不宜遲,我們趕快開始吧!!」聽到終於可以開始實作的消息之後,Wayne 高舉雙手並開心地說道。

「首先,用 VSCode 開啟我們剛剛用 Angular CLI 建立出來的 HelloAngular 專案...」


初次見面

Imgur

還記得這個畫面嗎?這是我們在第三天的時候,將用 Angular CLI 建立出來的專案,並且一樣用 Angular CLI 令其啟動之後,在 localhost:4200 上會看到的畫面 。(如果忘記怎麼啟動的話,趕快到點我複習一下!)

接著用 VSCode 開啟我們的 HelloAngular 專案(不知道怎麼開啟的話可以參考這篇文章,容我小小地偷懶一下!),應該會看到類似這樣子的畫面:

Imgur

打開 app.component.html 這個檔案:

Imgur

沒錯!仔細一看你會發現,這就是啟動之後的那個畫面的 HTML。但除了 base64String 型態的圖片之外,應該還有個地方會讓你有點在意:

Imgur

咦?!這個 {{ }} 符號好特別阿?!

沒錯!這是 Angular 用來綁定資料的其中一種方式─插值表達式,將要綁定的資料變數放在 {{ }} 裡面,Angular 就知道在這裡要將變數裡的資料放進去。

接著打開 app.component.ts 這個檔案:

Imgur

這個檔案只有短短 10 行,且有個名為 title 的變數:

Imgur

沒錯,這就是上述有提到的,Angular 將 title 這個變數裡的資料,放進了在 Template 中的 {{ title }} 位置裡,所以瀏覽器的畫面才有 Welcome to app! 的字樣。

如果想將其改為 Welcome to my first Angular App! 呢?試試看吧!


初次應用

接著我們做個難一點點的練習,這次利用臺北市政府資料開放平台臺北捷運列車到站站名資料,來做個「臺北捷運列車到站站名列表」好了!成果大概會長這樣:

Imgur

這次的練習除了會用到上述提到的插值表達式- {{ }} 之外,還可以練習使用結構型指令-*ngFor 以及管道 (pipe)date。 準備好了嗎?開始囉!

讓我們重新建立一個新專案(要用 HelloAngular 專案當然也是可以):

ng new MRTStationList

再根據臺北市政府資料開放平台的敘述找到我們需要資訊:

Imgur

然後開啟從臺北市政府資料開放平台下載的資料(如果開啟時發現是亂碼請莫急莫慌莫害怕,該資料是 Big-5 的編碼格式,稍微調整一下即可。點我看教學),並找個線上的格式美化器如 JSON Viewer 來美化一下資料格式,比較容易看得懂:

Imgur

接著用 VSCode 開啟剛剛建立的 MRTStationList 專案,將 app.component.html 裡的 HTML 全刪掉,替換成以下內容:

<table>
  <thead>
    <tr>
      <th></th>
      <th>列車進入月台車站之站名</th>
      <th>行駛目的地</th>
      <th>資料更新日期</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>南港展覽館</td>
      <td>頂埔</td>
      <td>2018-10-15 22:14:25</td>
    </tr>
  </tbody>
</table>

然後在終端機輸入以下指令:

ng serve

再用瀏覽器開啟 localhost:4200 之後,便會看到下圖:

Imgur

如此一來,我們算是完成初步的 Template 架構。接下來,讓我們把剛剛美化過後的資料放進來吧!怎麼做呢?首先,我們可以先新增一個名為 station-list.const.ts 的檔案,然後在裡面加上以下程式碼:

export const stationList = [

];

接著再把美化過後的的資料放進去(只要放 [] 裡面的就好囉!):

Imgur

哇咧?!怎麼都整片紅紅的?!是不是什麼地方做錯了?!別慌,把滑鼠指標停靠在有著紅色波浪底線的地方看看:

Imgur

原來是 tslint 在提醒你,雙引號 " 應該要被換成單引號 '。既然如此,我們就把它替換掉就好啦!請按下 Ctrl + H鍵(macOS 請按 command + option + F)開啟取代功能:

Imgur

並在「尋找」的欄位裡輸入 " 、「取代」的欄位裡輸入 ' 後,按下全部取代鍵:

Imgur

世界又再度恢復了和平~~,感謝飛天小女警的努力~~:

Imgur

接著到 app.component.ts 裡頭,我們把 stationList 給 import 進來使用,並將 title 改成 list,準備用來使用 list 裡的資料去讓畫面長出來:

import { Component } from '@angular/core';

// Constant
import { stationList } from './station-list.const';

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

  /**
   * 所有列車到站站名之資料
   *
   * @memberof AppComponent
   */
  list = stationList;

}

但我們要怎麼讓資料去幫我們把畫面長出來呢?先看一下 Template 的結構:

<table>
  <thead>
    <tr>
      <th></th>
      <th>列車進入月台車站之站名</th>
      <th>行駛目的地</th>
      <th>資料更新日期</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>南港展覽館</td>
      <td>頂埔</td>
      <td>2018-10-15 22:14:25</td>
    </tr>
  </tbody>
</table>

其實如果可以在 Template 寫程式的話,或許大家都知道該怎麼做:

<table>
  <!-- thead 省略 -->
  <tbody>
  
    <!-- 如果可以在 Template 裡寫程式的話 -->
    <!-- 就在這裡寫個 For 迴圈 -->
    <!-- 有多少筆資料,就有多少 <tr></tr> -->
    <tr>
      <td>1</td>
      <td>南港展覽館</td>
      <td>頂埔</td>
      <td>2018-10-15 22:14:25</td>
    </tr>
        
  </tbody>
</table>

沒錯!其實很多語言都可以直接在 HTML 裡寫程式,Angular 也可以!在這邊,我們會用到的 Template 語法是-*ngFor,所以程式碼就會變得像是這樣:

<table>
  <!-- thead 省略 -->
  <tbody>
    <tr *ngFor="let item of list">
      <td>1</td>
      <td>南港展覽館</td>
      <td>頂埔</td>
      <td>2018-10-15 22:14:25</td>
    </tr>
  </tbody>
</table>

儲存完檔案後,趕快到瀏覽器上看結果:

Imgur

哇!Angular 真的幫我們用資料把畫面長出來了耶?!不過怎麼都是一樣的資料?!這時候就要趕快搭配我們不久前學到的插值表達式{{ }}

<table>
  <!-- thead 省略 -->
  <tbody>
    <tr *ngFor="let item of list">
      <td>1</td>
      <td>{{ item.Station }}</td>
      <td>{{ item.Destination }}</td>
      <td>{{ item.UpdateTime }}</td>
    </tr>
  </tbody>
</table>

儲存完檔案之後一樣趕快到瀏覽器看看:

Imgur

哇!全部都按照資料產生出畫面了耶?!是不是覺得非常簡單、輕鬆呢?!這時候眼睛比較利的朋友可能會發現:咦?編號全部都是 1 啊?!沒錯,因為我們還沒有把索引加進來:

<table>
  <!-- thead 省略 -->
  <tbody>
    <tr *ngFor="let item of list; index as i">
      <td>{{ i + 1 }}</td>
      <td>{{ item.Station }}</td>
      <td>{{ item.Destination }}</td>
      <td>{{ item.UpdateTime }}</td>
    </tr>
  </tbody>
</table>

一樣改完要記得儲存,Angular CLI 才會幫你刷新頁面噢!加完索引的插值表達式之後,讓我們來看看畫面:

Imgur

這下子編號也完成了,只剩下最後一個資料更新日期的欄位還需要再調整一下。怎麼調整呢?!Angular 有提供一個原生的管道*(pipe)*- date 給我們使用。使用方式像是這樣:

<td>{{ item.UpdateTime | date: 'yyyy-MM-dd HH:mm:ss' }}</td>

如此一來這個功能就算完成啦!!

Imgur

剩下樣式的部份就看個人美感囉,來整理一下今天的程式碼吧!

app.component.html 的部份:

<table>
  <thead>
    <tr>
      <th></th>
      <th>列車進入月台車站之站名</th>
      <th>行駛目的地</th>
      <th>資料更新日期</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let item of list; index as i">
      <td>{{ i + 1 }}</td>
      <td>{{ item.Station }}</td>
      <td>{{ item.Destination }}</td>
      <td>{{ item.UpdateTime | date: 'yyyy-MM-dd HH:mm:ss' }}</td>
    </tr>
  </tbody>
</table>

app.component.ts 的部份:

import { Component } from '@angular/core';

// Constant
import { stationList } from './station-list.const';

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

  /**
   * 所有列車到站站名之資料
   *
   * @memberof AppComponent
   */
  list = stationList;

}

station-list.const.ts 的部份:

export const stationList = [
  {
    'Station': '三重國小站',
    'Destination': '南勢角站',
    'UpdateTime': '2018-10-15T22:14:41.557'
  },
  /*
   * 太長了,中間省略。
   */
  {
    'Station': '麟光站',
    'Destination': '南港展覽館站',
    'UpdateTime': '2018-10-15T22:14:41'
  }
];

怎麼樣?!Angular 滿好玩的吧?!很輕鬆、簡單地就可以實作一個小應用,如果今天換成 jQuery 來做這個功能的話,大概會變成像是這個樣子:

Imgur

是也不難啦,畢竟只是個小試牛刀而已。不過隨著程式的複雜程度提高,Angular 的優點會更明顯一些。下次我們再來做個比較複雜一點的應用吧!!


上一篇
[Angular 深入淺出三十天] Day 04 - 資料夾結構說明
下一篇
[Angular 深入淺出三十天] Day 06 - 基礎結構說明(一)
系列文
Angular 深入淺出三十天33

尚未有邦友留言

立即登入留言