Basic Angular Leaning[2]

Nunthinee Thongprom
5 min readOct 11, 2021

--

https://nunthineetp.medium.com/basic-anuglar-learning-1-f688bbc7c820

จากบทความที่แล้ว เราพูดถึง TypeScript พื้นฐานแบบคร่าวๆ ไปแล้ว ในบทความนี้เราจะเข้าสู่เนื้อหา Angular กัน

เตรียม Environment สำหรับก่อนสร้างโปรเจค Angular

โปรแกรม Visual Studio Code ใช้สำหรับการพัฒนา

download : https://code.visualstudio.com/download

Node.js

Node.js คือ Runtime Built สำหรับภาษา JavaScript

download : https://nodejs.org/en/download/

node -v   //พิมพ์คำสั่งใน cmd เพื่อเช็คว่าติดตั้งสมบูรณ์

ติดตั้ง Angular CLI

Angular CLI เป็น Command line interface ที่ช่วยให้เราสามารถเขียน Angular ได้

npm install -g @angular/cli@latest
npm install --save-dev @angular-devkit/build-angular
ตรวจสอบว่าติดตั้งสมบูรณ์หรือยังด้วยการเช็คเวอชั่น
ng v

ติดตั้ง TypeScript

npm install typescript --save-dev

ทดลองสร้างโปรเจค Angular

สร้างโปรเจค Angular ด้วยคำสั่ง

ng new <project-name>

เมื่อเปิดดูไฟล์ที่ Angular CLI สร้างขึ้นมาให้ก็จะเห็นโครงสร้างประมาณนี้

รัน Angular ด้วยคำสั่ง

ng serve //หรือ ng s 

ถ้ารันสำเร็จไม่มีข้อผิดพลาด ก็จะแสดง Compiled Successfully. ดังรูป และเปิด http://localhost:4200/

โครงสร้างเบื้องต้น

Index.html

Browser จะเห็นแค่ index.html เท่านั้น โดย angular จะสลับ component ที่ต้องการแสดงให้เอง

Package.json

เปรียบเสมือนบัตรประจำตัวของโปรเจค เช่น โปรเจคชื่ออะไร เวอชั่นเท่าไร ใช้ dependency อะไรบ้าง

Angular.json

เก็บ Config สำหรับ Angular Project เช่น Environtment

Main.ts

เป็นตัวกำหนดว่าจะให้ใครเป็น Root Module ในระบบ

Angular มีคอนเซปที่แบ่งสิ่งต่างๆ ที่เกี่ยวข้องกันออกเป็น Module ย่อยๆ โดยต้องมีอย่างน้อยหนึ่ง Module หลัก (Root Module)

Assets Directory

เก็บของที่จะใช้ในระบบ เช่น รูปภาพ font ฯลฯ

Environtment

เก็บการตั้งค่าที่ใช้ในการ Serve หรือ Build โปรเจค

E2E

คือ Unit Test ของ Angular

“All app has, at least, one module: the root one “

Module

  • ใช้ @NgModule decorators ที่ใช้ระบุว่า class นี้เป็น module
  • ทำหน้าที่รวบรวม Component, Diectives, Pipes และ Services ที่เกี่ยวข้องไว้ด้วยกัน

Angular ใช้ Decorators ในการระบุว่าควรจะ Compile Class นี้ยังไง (เหมือนใช้บอกว่ามันเป็นใคร ทำอะไร) เราจะเห็นมันเป็น class ธรรมดา จนกระทั่งเราแนบ Decorator ไปบอก Angular ว่า Class นี้เป็น Module นะ เป็น Component นะ

Properties ที่สำคัญ

Declarations

สำหรับประกาศ View Class (Component, Directive, Pipe) ที่อยู่ภายใน Module

Imports

สำหรับนำเข้า Module จากภายนอก เข้ามาใช้ภายใน Module ของเรา ยกตัวอย่างเช่น dependency ต่างๆ

Providers

สำหรับประกาศ Service ที่จะใช้ เพื่อให้ Class อื่นๆ ภายใต้ สามารถใช้ได้ด้วย

Bootstrap

กำหนดว่าจะให้ Component ไหนเป็น Component เริ่มต้นการทำงานของ Module (เฉพาะ Root Module เท่านั้น)

Exports

ส่งออก Class ภายใน Module ของตัวเอง ไปให้ Module อื่น ๆ ใช้งานได้

Componet

  • ใช้ @Component กำกับ
  • ทำหน้าที่ควบคุมการทำงานของ View Template (HTML) ผ่านทาง Properties (ตัวแปร) และ Function

Properties ที่สำคัญ

Selector

ชื่อที่อ้างถึง Component ที่ใช้บน HTML Template

selector จะบอกAngular ว่าให้สร้าง และเพิ่ม instance ของ Component นี้ เมื่อเจอTag ที่ตรงกับใน selector

TemplateURL

ไฟล์ HTML Template ที่ Component นี้ Support

StytleUrl

ไฟล์ CSS ที่ Component นี้ Support

Template

  • เป็นหน้าจอแสดงผล มีลักษณะเดียวกับ HTML แต่สามารถใช้ Angular Syntax ได้ด้วย

Directives หรือ Annotation

  • มี @Directive กำกับ
  • เป็น metadata แบบหนึ่ง ที่มีหน้าีท่บอกว่าจะให้แสดง Template ออกมาแบบไหน
  • Component เป็น Directive รูปแบบหนึ่ง ที่มี View เป็นของตัวเอง

มี 2 ประเภท

  1. Strctural Directives

ประเภทนี้จะเปลี่ยนแปลง Layout ของ DOM โดยการ เพิ่ม/ลบ/เปลี่ยน การแสดงผล เช่น *ngIF , *ngFor, *ngSwitch

2. Attribute Directives

ประเภทนี้จะเปลี่ยนรูปร่างหน้าตาหรือพฤติการณ์การทำงานของ DOM element เช่น ngModel, ngStyle, ngClass

Data Binding

เป็นการติดต่อสื่อสารระหว่าง View Template และ Component (HTML <-> TS)

แบ่งเป็น 2 แบบ

One-Way Data binding

การติดต่อทางเดียว คือ ส่งไป ไม่มีได้รับกลับ

  1. String Interpolation (การแทรกข้อความลงใน HTML)

=> {{ variable}}

// TypeScript
export class AppComponent{
title = 'Hello World'
}
// HTML
<div> {{ title }} </div>

2. Property Binding (ผูกค่ากับ Property ของ Element)

=> [ variable ]

// TypeScript
export class AppComponent{
isActive = true
}
//HTML
<button [disabled]="!isActive" > ADD </button>
or <div [property]="value" </div>

3. Event Binding

ส่ง event จากฝั่ง HTML ไปยัง Component เช่น เมื่อกดคลิกแล้ว จะให้ทำอะไร

=> (….)

//HTML
<button (click)="print()" >Print</button>
//TS
export class AppComponent{
print(){
console.log('hello')
}
}

Two-Way Binding

การผูกข้อมูลกลับไปมา ระหว่าง Component และ HTML

=> [(…)]

// TypeScript
export class AppComponent{
title = 'Hello World'
}
// HTML
<input type="text" [(ngModel)]="title">

อธิบายเพิ่มเติม เราประกาศค่าเริ่มต้น title ไว้คือคำว่า ‘Hello World’ ทีนี้เมื่อฝั่ง HTML เกิด event ซึ่งก็คือการพิมพ์ข้อความใน input ค่าที่พิมพ์ใหม่นั้นก็จะส่งกลับมาที่ตัวแรก title ในฝั่ง TS นั่นเอง

Service

  • มี @Service กำกับไว้
  • เป็น Class ตัวกลางที่ไว้ใช้แชร์ข้อมูลร่วมกันระหว่าง Component, Directive, Pipe และ Service

Dependency Injection

เป็นเทคนิคที่ใช้ในการส่งต่อ (inject) dependency แทนการสร้างขึ้นมาใหม่ สามารถ Inject Service ได้หลายวิธี เช่นผ่านทาง Provider หรือ Constructor

ข้อดี คือทำให้การทำงานระหว่าง Class ไม่มีการผูกมัดกัน

Injector เป็นผู้ดูแลกล่องเก็บ Service (Container) ถ้า Service ที่มีคนขอใช้นั้นมีอยู่ในกล่องอยู่แล้ว Injector จะส่งต่อ Service นั้นไปให้ใช้ แต่ถ้าไม่มีมันจะสร้างขึ้นมาใหม่แทน

Provider ทำหน้าที่จัดหาข้อมูลที่ใช้สำหรับสร้าง Dependency ให้แก่ Injector

ถ้าเราไม่ประกาศ Service ไว้ Provider & Injector จะไม่สามารถสร้าง Service ได้เนื่องจากไม่มีข้อมูลในการสร้าง

ตัวอย่าง Provider

@Injectable

  • ใส่ไว้เหนือ class เป็นการบอก Injector ว่า Class นี้สามารถนำไปสร้างเป็น Service ได้

provideIn : ‘root’ คืออะไร?

provideIn คือการระบุว่า Service นี้ Module ไหนนำไปใช้งานได้บ้าง Root แปลว่าทุก Module สามารถใช้งานได้

@NgModule

  • ใส่ไว้ใน provinders ของ NgModule แปลว่าจะใช้ได้เฉพาะ Module นี้

@Component

  • ใส่ไว้ใน provider ของ component แปลว่าสามารถใช้ได้แค่ภายใน Component นี้เท่านั้น หรือประกาศไว้ใน Constructor() ของ Component
  • * เลือกใช้แค่แบบใดแบบหนึ่ง **

อ้างอิงจาก https://medium.com/devnote/%E0%B8%97%E0%B8%B3%E0%B8%84%E0%B8%A7%E0%B8%B2%E0%B8%A1%E0%B8%A3%E0%B8%B9%E0%B9%89%E0%B8%88%E0%B8%B1%E0%B8%81%E0%B8%81%E0%B8%B1%E0%B8%9A-dependency-injection-%E0%B9%83%E0%B8%99-angular-880cbf483239

Sharing Data Between Component

เป็นการส่งข้อมูลระหว่าง Component

Input Directive

@Input

การส่งค่าจาก Parent ไปยัง Child Component

// Child ฝั่งลูกต้องประกาศ @Input รอรับตัวแปรที่แม่จะส่งมาให้
@Input('var') var:type
//Parent
<app-child [var]="value"></app-child>
ฝั่งแม่ ส่งค่าให้ลูกผ่าน property บน HTML

@Output

การส่งค่าจาก Child กลับไปยัง Parent Component จะใช้การ emit (ตะโกนออกไปบอกคนข้างนอก)

//Child
@Output() output = new EventEmiiter<type>()
this.output.emit( .... )
//Parent
<app-child (output)="result($event)" ></app-child>

Child Component ไม่สามารถระบุเฉพาะเจาะจงได้ว่าจะส่งค่ากลับไปให้แม่คนไหนกันแน่ (เพราะใครๆ ก็สามารถนำไปใช้ได้) ดังนั้นจึงจำเป็นต้องสร้าง Event ขึ้นมาเพื่อบอกว่าต้องการส่งข้อมูลออกไปนอก Component ตัวเอง

แล้ว Parent ที่ต้องการรับข้อมูลนั้น ให้สร้าง Function มารับค่าจาก Event นั้นเอา

Local Variable

  • เข้าถึง Public Property & Function ใน Child Component โดยการสร้าง Local Variable ขึ้นมา (ขึ้นต้นด้วย #…)
//Child TS
export class ChildComponent{
private title:string = 'Get Out'
public msg:string = 'Hello'
}
//Parent HTML
<app-child #child></app-child>
<div>{{child.msg}}</div> // ใช้งานได้
<div>{{child.title}}</div> // error ไม่สามารถเข้าถึง private บนchildได้

ViewChild

  • ใช้ @ViewChild ในการเข้าถึงข้อมูล Public บน Child Component
//Child
export class ChildComponent{
public print(){
console.log('hello')
}
}
//Parent HTML
<app-child #child></app-child>
//Parent TS
export class ParentComponent{
@ViewChild('child') childCom: ChildComponent
ngOnit(){
this.childCom.print() //hello
}
}

--

--

Nunthinee Thongprom
Nunthinee Thongprom

Written by Nunthinee Thongprom

บุคคลผู้ชื่นชอบการเขียน backend แต่โดนจับเขียน frontend ด้วย :(

No responses yet