Dev to webs {Coding…}

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

บทที่ 32: การอัปเดต Alpine.store


1. ความเข้าใจเกี่ยวกับการอัปเดต Alpine.store

Alpine.store ช่วยให้คุณสามารถแชร์ State ระหว่าง Component ต่าง ๆ และสามารถเพิ่ม, ลบ, หรืออัปเดตค่าภายใน Store ได้

  • การอัปเดต Store ใช้ได้ทั้งการเปลี่ยนค่าของ State โดยตรง และการใช้ฟังก์ชันภายใน Store เพื่อจัดการ State
  • การอัปเดต State ใน Store จะส่งผลกับทุก Component ที่ใช้งาน Store เดียวกัน

2. โครงสร้างการอัปเดต Store

ตัวอย่าง: การอัปเดตค่าภายใน Store
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('user', {
            name: 'John Doe',
            age: 30,
            updateName(newName) {
                this.name = newName;
            },
            updateAge(newAge) {
                this.age = newAge;
            }
        });
    });
</script>

คำอธิบาย:

  • updateName(newName) และ updateAge(newAge) เป็นฟังก์ชันใน Store สำหรับอัปเดตค่าของ name และ age

3. การเพิ่มข้อมูลใน Store

ตัวอย่าง 1: เพิ่มรายการใน Array
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('tasks', {
            items: [],
            addTask(task) {
                this.items.push(task);
            }
        });
    });
</script>

<div x-data>
    <input x-ref="taskInput" type="text" placeholder="Add a task">
    <button @click="$store.tasks.addTask($refs.taskInput.value)">Add Task</button>
    <ul>
        <template x-for="task in $store.tasks.items" :key="task">
            <li x-text="task"></li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • ฟังก์ชัน addTask(task) เพิ่มรายการใหม่ใน Array items
  • ปุ่ม Add Task ใช้ $store.tasks.addTask() เพื่อเพิ่มค่าจาก <input>

4. การลบข้อมูลใน Store

ตัวอย่าง 2: ลบรายการจาก Array
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('tasks', {
            items: ['Task 1', 'Task 2', 'Task 3'],
            removeTask(index) {
                this.items.splice(index, 1);
            }
        });
    });
</script>

<div x-data>
    <ul>
        <template x-for="(task, index) in $store.tasks.items" :key="task">
            <li>
                <span x-text="task"></span>
                <button @click="$store.tasks.removeTask(index)">Remove</button>
            </li>
        </template>
    </ul>
</div>

คำอธิบาย:

  • ฟังก์ชัน removeTask(index) ลบรายการจาก Array items ตามตำแหน่งที่ระบุ
  • ปุ่ม Remove ใช้ $store.tasks.removeTask(index) เพื่อลบรายการ

5. การอัปเดตข้อมูลใน Store

ตัวอย่าง 3: อัปเดตข้อมูล Object
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('profile', {
            user: { name: 'John Doe', age: 30 },
            updateProfile(newName, newAge) {
                this.user.name = newName;
                this.user.age = newAge;
            }
        });
    });
</script>

<div x-data>
    <p>Name: <span x-text="$store.profile.user.name"></span></p>
    <p>Age: <span x-text="$store.profile.user.age"></span></p>
    <input x-ref="nameInput" type="text" placeholder="New name">
    <input x-ref="ageInput" type="number" placeholder="New age">
    <button @click="$store.profile.updateProfile($refs.nameInput.value, $refs.ageInput.value)">
        Update Profile
    </button>
</div>

คำอธิบาย:

  • ฟังก์ชัน updateProfile(newName, newAge) อัปเดตค่า name และ age ใน Object user
  • ปุ่ม Update Profile ใช้ $store.profile.updateProfile() อัปเดตค่าจาก <input>

6. การอัปเดต State โดยตรง (ไม่แนะนำ)

ตัวอย่าง 4: อัปเดตค่าโดยตรง
<div x-data>
    <p>Current Theme: <span x-text="$store.theme.mode"></span></p>
    <button @click="$store.theme.mode = 'dark'">Set Dark Mode</button>
</div>

คำอธิบาย:

  • ค่า mode ใน Store theme ถูกอัปเดตโดยตรง
  • ข้อควรระวัง: วิธีนี้ไม่แนะนำในกรณีที่ State มีความซับซ้อนหรือเชื่อมโยงกับฟังก์ชันอื่น

7. การอัปเดตข้อมูลใน Store ร่วมกับ Component หลายตัว

ตัวอย่าง 5: แชร์ข้อมูลในหลาย Component
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('counter', {
            value: 0,
            increment() {
                this.value++;
            },
            decrement() {
                this.value--;
            }
        });
    });
</script>

<!-- Component 1 -->
<div x-data>
    <p>Counter: <span x-text="$store.counter.value"></span></p>
</div>

<!-- Component 2 -->
<div x-data>
    <button @click="$store.counter.increment()">Increment</button>
    <button @click="$store.counter.decrement()">Decrement</button>
</div>

คำอธิบาย:

  • Component ทั้งสองใช้ Store counter เดียวกัน
  • Component ที่สองสามารถอัปเดตค่า value และ Component แรกจะแสดงผลที่อัปเดต

8. การจัดการ State ซ้อนลึก

ตัวอย่าง 6: อัปเดตค่าใน Object ซ้อนลึก
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.store('settings', {
            preferences: {
                theme: 'light',
                notifications: true
            },
            updateTheme(newTheme) {
                this.preferences.theme = newTheme;
            },
            toggleNotifications() {
                this.preferences.notifications = !this.preferences.notifications;
            }
        });
    });
</script>

<div x-data>
    <p>Theme: <span x-text="$store.settings.preferences.theme"></span></p>
    <p>Notifications: <span x-text="$store.settings.preferences.notifications ? 'On' : 'Off'"></span></p>
    <button @click="$store.settings.updateTheme('dark')">Set Dark Theme</button>
    <button @click="$store.settings.toggleNotifications()">Toggle Notifications</button>
</div>

คำอธิบาย:

  • ฟังก์ชัน updateTheme() และ toggleNotifications() ใช้จัดการค่าใน Object preferences ซึ่งซ้อนลึกใน Store settings

9. ข้อควรระวังในการอัปเดต Store

  1. ไม่ควรอัปเดต State โดยตรง:
    • ควรใช้ฟังก์ชันใน Store เพื่อจัดการข้อมูล เพื่อรักษาความสมบูรณ์ของ State
  2. หลีกเลี่ยงการอัปเดต State ที่ซับซ้อนใน Component:
    • ควรให้ Store เป็นผู้จัดการ State แทน
  3. ระวังผลกระทบกับ Component อื่น:
    • การเปลี่ยนแปลง Store อาจมีผลกับ Component ที่ใช้ Store เดียวกัน

สรุป

ในบทนี้ คุณได้เรียนรู้วิธีการอัปเดต State ใน Alpine.store ทั้งการเพิ่ม, ลบ, และอัปเดตค่าใน State ตัวอย่างแสดงถึงการใช้งานใน Array, Object, และการแชร์ข้อมูลระหว่าง Component หลายตัว การใช้งาน Store อย่างเหมาะสมจะช่วยเพิ่มความยืดหยุ่นและจัดการข้อมูลได้ง่ายในโปรเจกต์ที่ซับซ้อน!