Dev to webs {Coding…}

เรียนรู้การพัฒนาซอฟเวอร์ เพื่อความรู้ที่ยั่งยืน

บทที่ 28: การใช้งาน $watch


1. ความเข้าใจเกี่ยวกับ $watch

$watch เป็นคำสั่งใน Alpine.js ที่ช่วยให้คุณสามารถติดตามการเปลี่ยนแปลงของค่าภายใน State และรันฟังก์ชันเมื่อค่าที่กำหนดมีการเปลี่ยนแปลง

  • ใช้สำหรับการตรวจจับการเปลี่ยนแปลงของ State แบบ Reactive
  • ช่วยจัดการการอัปเดตหรือการทำงานที่ต้องตอบสนองต่อการเปลี่ยนแปลงค่า

2. โครงสร้างพื้นฐานของ $watch

<div x-data="{ state: '', initializeWatcher() { 
    this.$watch('state', value => { 
        console.log(`State changed to: ${value}`); 
    }); 
} }" x-init="initializeWatcher()">
    <!-- Content -->
</div>

คำอธิบาย:

  • this.$watch('state', callback) ใช้ติดตามค่า state
  • callback คือฟังก์ชันที่ถูกรันเมื่อ state เปลี่ยนแปลง

3. การใช้งาน $watch เบื้องต้น

ตัวอย่าง 1: ติดตามค่าใน State
<div x-data="{ name: '', initializeWatcher() { 
    this.$watch('name', value => { 
        console.log(`Name changed to: ${value}`); 
    }); 
} }" x-init="initializeWatcher()">
    <label for="name">Name:</label>
    <input type="text" id="name" x-model="name" placeholder="Enter your name">
</div>

คำอธิบาย:

  • เมื่อค่าของ name เปลี่ยน, this.$watch จะรัน callback และพิมพ์ข้อความลงใน Console

4. การใช้งาน $watch กับฟังก์ชัน

ตัวอย่าง 2: รันฟังก์ชันเมื่อค่าเปลี่ยน
<div x-data="{ counter: 0, logChange(value) { 
    console.log(`Counter updated to: ${value}`); 
}, initializeWatcher() { 
    this.$watch('counter', this.logChange); 
} }" x-init="initializeWatcher()">
    <p>Counter: <span x-text="counter"></span></p>
    <button @click="counter++">Increment</button>
</div>

คำอธิบาย:

  • ฟังก์ชัน logChange(value) จะถูกเรียกเมื่อ counter เปลี่ยนแปลง
  • this.$watch ผูกฟังก์ชัน logChange กับค่า counter

5. การใช้งาน $watch กับค่าที่ซับซ้อน

ตัวอย่าง 3: ติดตามค่าใน Object
<div x-data="{ user: { name: '', age: 0 }, initializeWatcher() { 
    this.$watch('user', value => { 
        console.log(`User updated: Name = ${value.name}, Age = ${value.age}`); 
    }); 
} }" x-init="initializeWatcher()">
    <label for="name">Name:</label>
    <input type="text" id="name" x-model="user.name" placeholder="Enter name">
    <label for="age">Age:</label>
    <input type="number" id="age" x-model="user.age" placeholder="Enter age">
</div>

คำอธิบาย:

  • this.$watch('user', callback) ใช้ติดตามการเปลี่ยนแปลงใน Object user
  • ค่า name และ age จะถูกตรวจจับพร้อมกัน

6. การใช้งาน $watch กับค่าที่ซ้อนลึก

ตัวอย่าง 4: ติดตามค่าซ้อนลึกใน Object
<div x-data="{ settings: { theme: { color: 'light' } }, initializeWatcher() { 
    this.$watch('settings.theme.color', value => { 
        console.log(`Theme color changed to: ${value}`); 
    }); 
} }" x-init="initializeWatcher()">
    <label for="color">Theme Color:</label>
    <select id="color" x-model="settings.theme.color">
        <option value="light">Light</option>
        <option value="dark">Dark</option>
    </select>
</div>

คำอธิบาย:

  • this.$watch('settings.theme.color', callback) ติดตามการเปลี่ยนแปลงของ color ใน Object ซ้อนลึก
  • เมื่อเลือก Theme Color ใหม่, ฟังก์ชันใน $watch จะถูกรัน

7. การใช้งาน $watch กับ Asynchronous Tasks

ตัวอย่าง 5: ดึงข้อมูลเมื่อค่าเปลี่ยน
<div x-data="{ query: '', results: [], fetchResults(query) { 
    fetch(`https://jsonplaceholder.typicode.com/posts?title_like=${query}`)
        .then(response => response.json())
        .then(data => { 
            this.results = data; 
        }); 
}, initializeWatcher() { 
    this.$watch('query', value => { 
        if (value.length > 2) this.fetchResults(value); 
    }); 
} }" x-init="initializeWatcher()">
    <label for="query">Search:</label>
    <input type="text" id="query" x-model="query" placeholder="Search posts...">
    <ul>
        <template x-for="result in results" :key="result.id">
            <li x-text="result.title"></li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • ฟังก์ชัน fetchResults(query) ดึงข้อมูลจาก API เมื่อ query เปลี่ยนและมีความยาวมากกว่า 2 ตัวอักษร

8. ข้อควรระวังในการใช้ $watch

  1. ฟังก์ชัน Callback ซับซ้อน:
    • หาก Callback มีการประมวลผลมาก อาจส่งผลต่อประสิทธิภาพ
  2. การติดตามค่าซ้อนลึก:
    • การตรวจจับค่าซ้อนลึกใน Object อาจต้องการการจัดการที่ระมัดระวัง
  3. การใช้งานกับ Asynchronous:
    • ต้องจัดการผลลัพธ์อย่างเหมาะสม เช่น การตรวจจับข้อผิดพลาด (Error Handling)

สรุป

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับการใช้ $watch ใน Alpine.js เพื่อติดตามการเปลี่ยนแปลงของค่าภายใน State และรันฟังก์ชันตอบสนองต่อการเปลี่ยนแปลง ตัวอย่างครอบคลุมการใช้งานกับค่าแบบง่าย, Object, ค่าซ้อนลึก และการเรียกใช้งานร่วมกับ Asynchronous Tasks ในบทถัดไป เราจะศึกษาการใช้งาน $dispatch เพื่อส่ง Event ภายใน Component!