ก่อนลงรายละเอียดต่อไป จะขอใช้คำย่อว่า DI แทน dependency injection หรือที่
เรียกว่า การนำเข้า service class ใน Angular App ซึ่งเป็นสิ่งที่มีความสำคัญมาก
ในการออกแบบ App ของเรา
DI คือรูปแบบการเขียนโค้ดที่รับเอา service class จากภายนอกเข้ามาใช้งานใน class
แทนที่จะสร้างขึ้นมาเอง
เรามาเริ่มศึกษาโดยต่อยอดจากบทความที่ผ่านมา
(ทบทวนบทความได้ที่)
การส่งค่าข้อมูลจาก Form ใน Angular app เบื้องต้น
https://www.ninenik.com/content.php?arti_id=778 via @ninenik
ให้เราสร้างไฟล์ชื่อ staff-list.component.html เป็นไฟล์ html template สำหรับ
แสดงรายชื่อ staff ดังนี้
ไฟล์ staff-list.component.html
<br> <div class="container"> <table class="table table-condensed"> <tr class="active"> <th>ID</th> <th>Name</th> <th>Age</th> <th>Department</th> </tr> <tr *ngFor="let staff of staffs"> <td>{{staff.id}}</td> <td>{{staff.name}}</td> <td>{{staff.age}}</td> <td>{{staff.department}}</td> </tr> </table> </div>
จากนั้นให้สร้างไฟล์ชื่อ mock-staffs.ts เป็นไฟล์สำหรับจำลองข้อมูล staff
ไฟล์ mock-staffs.ts
import { Staff } from './staff' export var STAFFS:Staff[] = [ {id:1,name:'John Smoke',department:'IT Support',age:27}, {id:2,name:'Linda Pink',department:'Accounting',age:30}, {id:3,name:'Lisa Mour',department:'Marketing',age:33} ];
สังเกตว่าไฟล์นี้มีการ import class ชื่อ Staff ซึ่งเป็น Object class ที่กำหนด
คุณสมบัติหรือรูปแบบ property ของ Staff Object ด้านใน เช่น id,name,age และ department
ไฟล์ mock-staffs.ts นี้จะทำการจำลองรายชื่อของ staff ไว้ในตัวแปรที่ชื่อ
STAFFS ซึ่งมี type หรือประเภทตัวแปรเป็น Array ของ Staff Object ตามรูปแบบ
var STAFFS:Staff[] = [{},{},{}];
และส่งออกค่าตัวแปรนี้ด้วยคำสั่ง export
ต่อไปให้เราสร้างไฟล์ชื่อ staff-list.component.ts สำหรับทำคำสั่งต่างๆ ในการนำข้อมูล
staff จากไฟล์จำลองช้อมูล mock-staffs.ts มาแสดงในไฟล์ template ที่เราสร้างไว้ก่อนหน้า
ไฟล์ staff-list.component.ts
import { Component } from '@angular/core' import { STAFFS } from './mock-staffs' @Component({ moduleId: module.id, selector: 'staff-list', templateUrl: `./staff-list.component.html`, }) export class StaffListComponent { staffs = STAFFS; }
จะเห็นว่ามีการ import ตัวแปรข้อมูล staff จากไฟล์จำลองข้อมูลมาใช้งาน โดยเราได้นำค่า
ตัวแปร STAFFS มากำหนดค่าให้กับ property ของ StaffListComponent ที่ชื่อ staffs
staffs = STAFFS;
รวมถึงมีการใช้งาน templateUrl เพื่อใช้งาน template จากไฟล์ staff-list.component.html
ให้ไปแสดงในส่วน selector ที่ชื่อ staff-list ซึ่งเราจะไปกำหนดแท็ก <staff-list> ในไฟล์
app.component.ts เพื่อใช้งาน
ให้เราเปิดไฟล์ app.component.ts และแก้ไขส่วนของ template โดยให้เปลี่ยนเป็นแท็ก
<staff-list> ตาม selector ของ class ที่เราจะนำมาแสดง
ไฟล์ app.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<staff-list></staff-list>`, }) export class AppComponent { }
และส่วนสุดท้ายอีกไฟล์ที่เราต้องจำไว้เสมอว่า เมื่อมีการสร้าง Component class ใหม่
ขึ้นมาใช้งาน เราจะต้องทำการ import class นั้นๆ พร้อมทั้งกำหนดค่าเพิ่มเข้าไปใน
declarations metadata ของ NgModule ในไฟล์ app.module.ts เสมอ ทุกครั้ง
ไฟล์ app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { UserComponent } from './components/user.component'; import { StaffFormComponent } from './components/staff-form.component'; import { StaffListComponent } from './components/staff-list.component' @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, UserComponent, StaffFormComponent, StaffListComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
ที่นี้เรามาดูผลลัพธ์ที่ได้ เมื่อเราทำการรัน App จะได้เป็นดังนี้
การทำงานของโปรแกรมที่ได้ผลลัพธ์ดังรูปคือ StaffListComponent class รับข้อมูล
รายชื่อ staff จากตัวแปร STAFFS ซึ่งถูกส่งออกมาจากไฟล์ mock-staffs.ts เป็นข้อมูล
จำลองสำหรับทดสอบ
การใช้งานข้างต้นนี้ ยังไม่มีการนำเข้า service class มาใช้งาน และเราจะศึกษาต่อ
ในลำดับต่อไป
สร้าง service class เพื่อเรียกใช้ Dependency Injection
ให้เราสร้างไฟล์ staff.service.ts โดยมีการกำหนด service class ชื่อ StaffService และมี
คำสั่ง getStaffs ซึ่งจะไปเรียกข้อมูลจำลองจากไฟล์ mock-staffs.ts มาใช้อีกที
ไฟล์ staff.service.ts
import { Injectable } from '@angular/core'; import { STAFFS } from './mock-staffs'; @Injectable() export class StaffService { getStaffs() { return STAFFS; } }
การกำหนด @Injectable() เป็นการแสดงถึงว่า class นี้เป็น sevice class หรือ
เรียกว่า Injector ที่จะถูกนำไปใช้งานใน class อื่นๆ
หมายเหตุ: ตัวอย่าง service class ข้างต้น เป็นรูปแบบ service จำลองเท่านั้น ยังไม่ใช้
รูปแบบ service ที่ใช้งานจริงจังทั่วไป ซึ่งปกติแล้ว ถ้า App จะดึงข้อมูลจาก server
การกำหนด API จะเป็นในลักษณะการรับค่าส่งค่าข้อมูลที่เกิดไม่พร้อมกัน เช่น การใช้งาน
รูปแบบ Ajax ที่ทำการส่งคำสั่งไปดึงข้อมูลและรอข้อมูลส่งกลับมา จากนั้นจึงค่อยนำข้อมูล
นั้นๆ ไปใช้งาน แบบนี้เป็นต้น แต่ในตัวอย่างของเรา การใช้คำสั่งข้างต้น เพื่อจำลอง
การทำงานของ service class ก็เพียงพอแล้ว
ในตอนหน้า เราจะมาดูในเรื่องของการตั้งค่าและใช้งาน Injector หรือ service class ที่เราสร้าง
ขึ้นมา เพื่อใช้งานต่อไป รอติดตาม