Devdit
 

Angular จัดการ state ด้วย NgRx

357

บทความนี้สอนเขียนโปรแกรมจัดการ state (State Management) ใน Angular ด้วย NgRx ตัวอย่างนี้เราจะเขียนโปรแกรมที่มีปุ่มกดเพื่อเพิ่ม, ลบ และคืนค่า state พร้อมกับแสดงค่า state ดังกล่าวที่หน้าเว็บไซต์ โดยมีการใช้งานร่วมกับ Bootstrap เพื่อเพิ่มความสวยงามของโปรแกรม มีขั้นตอนดังนี้

 

บทความนี้ใช้ Angular เวอร์ชัน 16.2.x, NgRx เวอร์ชัน 16.3.x, Bootstrap เวอร์ชันล่าสุด และ Angular Project ชื่อ my-rx ก่อนเขียนโปรแกรมตามต้องติดตั้ง NgRx และ Boostrap ให้เรียบร้อยก่อน

- วิธีสร้าง Angular Project
https://www.devdit.com/post/4238/วิธีสร้าง-angular-project
- วิธีติดตั้ง NgRx
https://www.devdit.com/post/4241/วิธีติดตั้ง-ngrx-ใน-angular
- วิธีติดตั้ง Boostrap
https://www.devdit.com/post/4239/วิธีติดตั้ง-bootstrap-ใน-angular

 

ตัวอย่าง Angular จัดการ state ด้วย NgRx

1. สร้างไฟล์ชื่อ counter.actions.ts ไว้ใน folder app และเขียนโค้ดดังนี้

import { createAction } from '@ngrx/store';

export const increment = createAction('Increment');
export const decrement = createAction('Decrement');
export const reset = createAction('Reset');

จากโค้ดมี 3 actions คือ increment, decrement และ reset ซึ่งจะไม่มีส่วนการทำงานของโค้ด 

 

2. สร้างไฟล์ counter.reducer.ts ไว้ใน folder app และเขียนโค้ดดังนี้

import { createReducer, on } from '@ngrx/store';
import { increment, decrement, reset } from './counter.actions';

export const counterState = 0;

export const counterReducer = createReducer(
    counterState,
    on(increment, (state) => state + 1),
    on(decrement, (state) => state - 1),
    on(reset, (state) => 0),
);

จากโค้ดนำ actions ทั้ง 3 เพื่อเขียนโค้ด อธิบายได้ดังนี้

2.1 ตัวแปร state ชื่อ counterState

2.2 increment ทำหน้าที่บวกค่า state จากเดิมเพิ่ม 1

2.3 decrement ทำหน้าที่ลบค่า state จากเดิมลง 1

2.4 reset ทำหน้าที่คืนค่า state เป็น 0

 

3. เปิดไฟล์ /src/app/app.module.ts และเพิ่มโค้ด 2 ส่วนดังนี้

3.1 เพิ่ม import StoreModule และ counterReducer ไว้ด้านบนของโค้ด

import { StoreModule } from '@ngrx/store';
import { counterReducer } from './counter.reducer';

3.2 เพิ่ม StoreModule.forRoot ไว้ใน imports

@NgModule({
  imports: [
    StoreModule.forRoot({ counterState: counterReducer })
    ...
  ],

โค้ดนี้เป็นการนำ counterReducer ที่สร้างในขั้นตอนที่ 2 มาใช้กับ components ต่างๆ ที่ต้องการผ่านตัวแปรชื่อ counterState

 

4. เปิดไฟล์ src/app/app.component.ts และเพิ่มโค้ดดังนี้

4.1 เพิ่ม import Store และ increment, decrement, reset ไว้ด้านบนของโค้ด

import { Store } from '@ngrx/store';
import { increment, decrement, reset } from './counter.actions';

4.2 ภายใน class AppComponent เพิ่มโค้ดดังนี้

export class AppComponent {
  counterState$: Observable<number>
  title = 'my-rx';
  
  constructor(private store: Store<{ counterState: number }>) {
    this.counterState$ = store.select('counterState');
  }

  increment() {
    this.store.dispatch(increment());
  }

  decrement() {
    this.store.dispatch(decrement());
  }

  reset() {
    this.store.dispatch(reset());
  }
}

จากโค้ดอธิบายส่วนสำคัญได้ดังนี้

4.1 counterState$ ใช้สำหรับอ้างถึงตัวแปร state ชื่อ counterState

4.2 สร้างตัวแปร store จาก Store ซึ่งเป็น Object ที่เก็บ state ทั้งหมดของโปรแกรม

4.3 กำหนดให้ตัวแปร this.counterState$ ชี้ไปที่ counterState ด้วยคำสั่ง select

4.4 ฟังก์ชัน increment ใน component (.ts) เรียกใช้ increment ใน action

4.5 ฟังก์ชัน decrement ใน component (.ts) เรียกใช้ decrement ใน action

4.6 ฟังก์ชัน reset ใน component (.ts) เรียกใช้ reset ใน action

 

5. เปิดไฟล์ src/app/app.component.html และเขียนโค้ดดังนี้

<div class="d-flex justify-content-center align-items-center" style="height: 100vh;">
  <div class="container">
    <div class="row text-center">
      <div class="col-12 mb-2"><h4>ค่า counterState เท่ากับ {{ counterState$ | async }}</h4></div>
      <div class="col-12">
        <button class="btn btn-primary mx-2" (click)="increment()">เพิ่มค่า</button>
        <button class="btn btn-danger mx-2" (click)="decrement()">ลดค่า</button>
        <button class="btn btn-warning mx-2" (click)="reset()">คืนค่า</button>
      </div>
    </div>
  </div>
</div>

โค้ดนี้คือส่วนแสดงผลที่ใช้ Bootstrap ส่วนสำคัญคือ

5.1 {{ counterState$ | async }} แสดงผล state counterState ที่หน้าเว็บไซต์

5.2 (click)="increment()" เมื่อกดคลิกจะทำงานฟังก์ชัน increment ใน components (.ts) และเรียกใช้ increment ใน action

5.3 (click)="decrement()" เมื่อกดคลิกจะทำงานฟังก์ชัน decrement ใน components (.ts) และเรียกใช้ decrement ใน action

5.4 (click)="reset()" เมื่อกดคลิกจะทำงานฟังก์ชัน reset ใน components (.ts) และเรียกใช้ reset ใน action

 

6. ทดลองรันโปรแกรมด้วยคำสั่ง ng serve และเข้า URL http://localhost:4200/ หากสำเร็จจะแสดงหน้าจอโปรแกรม และปุ่มกด 3 ปุ่มที่สามารถเพิ่ม, ลด และคืนค่าตัวแปร counterState ได้

ng serve

 

สรุป Angular จัดการ state ด้วย NgRx มีขั้นตอนดังนี้
1. สร้าง action ซึ่งเป็นส่วนเก็บรายชื่อฟังก์ชันที่จะทำงานกับ state

2. สร้าง reducer ซึ่งเป็นส่วนเขียนโค้ดจากชื่อฟังก์ชันที่เขียนไว้ในไฟล์ action

3. นำเข้า reducer ใน app.module.ts

4. ที่ component ส่วนของโค้ด (.ts) ให้ selector เลือก state ที่ต้องการด้วยคำสั่ง select หรือเขียนฟังก์ชันเพื่อเรียกใช้ฟังก์ชันจาก action

5. ที่ component ส่วนของการแสดงผล (.html) ให้เรียกใช้งานตัวแปรดังกล่าวด้วย <ชื่อ state>$ | async

แก้ไข 5 เดือนที่แล้ว
ชอบ
ลิ้งก์
แชร์
Devdit มีช่อง YouTube แล้ว
เราสร้างวิดีโอเกี่ยวกับเทคโนโลยี ทำตามง่ายๆ