มาทำ Infinite Scroll จาก Firebase Firestore ใน Angular กัน + Virtual scroll
หลายคนที่เข้ามาในบทความนี้ อาจจะประสบปัญหาในการดึงข้อมูลจาก Firebase Firestore มาแสดงผลหรือต้องการหาวิธีที่จะดึงข้อมูลจาก Firestore ออกมาใช้ใน angular เนื่องจากได้ศึกษา ทดลอง แก้ไขด้วยตัวเองมาแล้วจึงอยากจะนำวิธีมาแบ่งปันแก่ทุกคนค่า
และ Angular Material ก็มีของเล่นที่น่าสนใจคือ Virtual scroll จึงนำมาเป็นของแถมให้ทุกคนได้รู้จักและใช้กันค่า
มาเริ่มกันเลยยยยยยยย~~~~
ขั้นตอนแรก สร้างโปรเจ็ค Angular
1. ติดตั้ง the Angular CLI แบบ globally
npm install @angular/cli -g
2. สร้าง Angular Application
ng new infinite-scroll
หลังใช้คำสั่ง จะมีคำถามว่าจะเพิ่ม Angular routing หรือไม่ และใช้ style sheet แบบไหน
ซึ่งในโปรเจกต์ตัวอย่าง จะเพิ่ม routing และใช้ style sheet แบบ Less
3. หลัง Angular CLI สร้างโปรเจกต์เรียบร้อย ดูซิว่าใช้ได้จริงไหม?
cd my-app
ng serve
ไปที่ http://localhost:4200/
ขั้นตอนที่ 2 สร้าง Cloud Firestore 🔥
ก่อนที่จะดึงข้อมูลมา เราจะต้องมี Cloud Firestore ของตัวเองกันก่อนนะคะ😊
สร้างโปรเจกต์ใน Firebase
ไปที่ https://console.firebase.google.com เพื่อสร้างโปรเจกต์ใหม่
เจอกับหน้าสร้างโปรเจกต์ กรอกชื่อที่ต้องการเลย
เปิดใช้ Google Analytics (เปิดหรือไม่เปิดก็ได้ค่า)
หากเปิด Google Analytics จะมีให้สร้างบัญชี
สร้าง Database ประเภท Cloud Firestore
โดยไปที่หน้า database และกดที่ สร้างฐานข้อมูล
เลือกโหมดทดสอบ โดยเราสามารถแก้ไข Firestore rule ได้ในภายหลัง
เลือกตำแหน่งที่ตั้งตามต้องการ
เชื่อมต่อ Angular โปรเจกต์กับ Firestore
ในการเชื่อมต่อกับ Firestore จำเป็นต้องติดตั้ง firebase
และ@angular/fire
เพื่อที่จะใช้ AngularFireModule
และ AngularFirestoreModule
โดยใช้คำสั่ง
npm i --save firebase @angular/fire
กลับไปที่ Firebase เพื่อเชื่อมโปรเจกต์ของเรากับ Firebase
เข้าไปที่ไฟล์ app.module.ts เพื่อเรียกใช้ Firebase ใน Angular
ขั้นตอนที่ 3 สร้าง Scrollable Directive
เพื่อตรวจสอบตำแหน่งของ scrollPosition
ด้วยคำสั่ง
ng g directive scrollable
เราใช้ directive เพื่อบอกว่า ตอนนี้ scrollbar อนู่ที่ตำแหน่งบนสุด หรือ ล่างสุดของหน้าเว็บ ซึ่งได้การใช้ @Output และ EventEmitter จากฟังก์ชั่นที่จากขึ้นมา
เรียกใช้ Directive ใน component
เรียกใช้ directive ใน tag ที่จะตรวจสอบตำแหน่งของ scrollbar
ได้ scrollableDirective
ที่ทำงานได้อย่างสมบูรณ์ 🎆
ขั้นตอนที่ 4 สร้าง Service เพื่อใช้แสดงผลข้อมูลจาก Firestore 🔥
สร้าง Service เพื่อใช้ดึงข้อมูลจาก Firestore มาแสดงผล ด้วยคำสั่ง
ng g service pagination
สร้าง interface query เพื่อใช้ในการดึงข้อมูล
เรามาทำความรู้จักกันคร่าว ๆ กับฟังก์ชั่นต่าง ๆ ใน service กันก่อนนะคะ
mapAndUpdate()
เมื่อมีการร้องขอข้อมูลเกิดขึ้น จะนำข้อมูลที่ได้มาไปเก็บไว้ และตรวจสอบว่าข้อมูลที่ดึงมาครบรึยัง โดยเก็บข้อมูลตัวล่าสุดไว้ที่ตัวแปรlatestEntry
init()
ใช้คำสั่งในการดึงข้อมูลจาก collection ใน Firestore โดยจะเก็บข้อมูลไว้ใน Observable ชื่อdata
ซึ่งคอยรับข้อมูลชุดถัดไปผ่านคำสั่งscan
ใน RxJS โดยข้อมูลที่ถูกดึงมาใหม่จะถูกเชื่อมเข้ากับชุดข้อมูลเริ่มต้นmore()
ฟังก์ชั่นเพื่อดึงข้อมูลในแต่ละรอบ โดยจะนำตำแหน่งล่าสุดของข้อมูลใส่ในstartAfter
เพื่อดึงข้อมูลตัวถัดไปออกมา
ขั้นตอนที่ 5 สร้าง component Loading
สร้าง component Loading เพื่อแสดงผลให้แก่ผู้ใช้เห็นในระหว่างที่รอการดึงข้อมูล
ng g component loading-spinner
สำหรับการแสดงผล Loading สามารถเลือกตัว demo ได้จาก spinkit โดย copy โค้ดในส่วน html และ style ไปไว้ใน loading-spinner component
ขั้นตอนที่ 6 สร้าง infinite scroll ที่สมบูรณ์ 😎
เรียกใช้ service ใน component เพื่อดึงข้อมูลมาแสดงผล
- ใช้
init(path, field, opts?)
เพื่อดึงข้อมูลมาแสดงผล
init(path: string, field: string, opts: {
limit: number,
reverse?: boolean,
prepend?: boolean
})
- path — ชื่อของ collection ที่ใช้
- field — ชื่อข้อมูลที่ใช้เรียงข้อมูล
- limit — จำนวน doc ที่จะดึงมาในแต่ละครั้ง
- reverse — สลับการเรียงลำดับ มากไปน้อย หรือ น้อยไปมาก
- prepend — เพิ่ม doc ตัวที่ดึงมาใหม่ที่ด้านบนของชุดข้อมูล
2. หลังดึงข้อมูลเริ่มต้น ใช้คำสั่ง more()
เพื่อดึงข้อมูลที่เหลือมา โดยเรียกใช้คำสั่งเมื่อ scrollbar อยู่ตำแหน่งล่างสุด
service จะมี Observables 3 ตัว ที่เราจะนำมาใช้ใน HTML
data
- Array ของข้อมูลที่ดึงมาจาก Firestoreloading
- จะเป็น true เมื่อกำลังดึงข้อมูลจาก Firestoredone
- จะเป็น true เมื่อข้อมูลถูกดึงออกมาครบแล้ว
ตามโค้ดด้านล่างในส่วนของ app.component.html
หากข้อมูลยังโหลดไม่เสร็จ จะแสดง app-loading-spinner หากโหลดเสร็จจึงจะแสดงผลข้อมูลที่ดึงมาได้
สำเร็จแล้ววววววว!!! มากันที่โบนัส
Virtual scroll คือ…..
การแสดงผลเฉพาะรายการข้อมูลส่วนพอดีกับขนาดหน้าจอที่ผู้ใช้เห็น เนื่องจากการโหลดข้อมูลมาครั้งละจำนวนมากหลายร้อยข้อมูล จะส่งผลให้ browser ทำงานช้า
โดย virtual scroll จะไม่ทำการสร้างการแสดงผลข้อมูลทั้งหมดขึ้นจริงๆ แต่จะสร้างการแสดงผลเฉพาะในส่วนที่ถูกมองเห็นได้ในหน้าจอ ส่วนอื่นที่เหลือจะมีแค่ตัวข้อมูลเท่านั้นซึ่งแตกต่างกับ infinite scroll ที่ต้องเลื่อนไปที่ตำแหน่งที่กำหนดไว้ จึงจะแสดงผลรายการที่เหลือ
หากต้องการศึกษารายละเอียดเพิ่มเติม สามารถอ่านได้ที่
มาเริ่มใช้ Virtual scroll กันเลย!!
ติดตั้ง @angular/cdk เพื่อใช้งาน Angular CDK scrolling
npm install @angular/cdk --save
เรียกใช้ CdkScrollableModule และ ScrollingModule ใน app.module.ts
สำเร็จไปเรียบร้อยกับการแสดงผลที่หนึ่งวิธีผ่าน Virtual scroll ซึ่งจะทำให้หน้าเว็บของเรานั้นแสดงผลได้เร็วยิ่งขึ้น
แต่เท่านี้ยังไม่พอ!!! Service เมื่อเราสร้างครั้งแรกจะเป็นแบบ Singleton (Service ที่ได้จะเป็น Instance ตัวเดิม) ซึ่งหากเราต้องการเรียกใช้หลาย ๆ Component และไม่มีปัญหาเรื่อง Instance จะต้องประกาศเป็น Factory providers ด้วยวิธีต่อไปนี้…
สร้าง factory function
เรียกใช้ CatListServiceProvider
ใน app.component.ts
สำเร็จแล้ววววว🎆🎆 หากจะเรียกใช้ Service นี้ใน Component อื่น สามารถสร้าง Factory Function ใหม่ และเพิ่ม Provider ตัวที่สร้างขึ้นมา ใน Component ที่เรียกใช้งาน ตามตัวอย่างข้างบนได้เลยค่า👍
หวังว่าบทความนี้จะสร้างประโยชน์ให้แก่ผู้อ่านไม่มากก็น้อยนะคะ หากมีข้อติชม สามารถ comment ไว้ที่บทความได้เลย แล้วพบกันใหม่ค่า😘
🔅🔅🔅หมายเหตุ🔅🔅🔅
✔หากใส่ providedInroot ใน Service แต่ยังเรียกใช้ Factory Provider แยกแต่ละ component จะได้ Service ที่เป็น FACTORY
❗❗ แต่ถ้าลบ providedInroot ออก และไม่เรียกใช้ Factory Provider จะได้ Service ที่เป็น SINGLETON
//code ส่วน providedIn root ใน Service
@Injectable({
providedIn: ‘root’,
})
💖source code :