Now.js Framework Documentation
data-model
data-model
ภาพรวม
data-model สร้าง two-way data binding ระหว่าง form inputs และ data state การเปลี่ยนแปลงใน input จะอัพเดทข้อมูล และการเปลี่ยนแปลงข้อมูลจะอัพเดท input
ใช้เมื่อ:
- Form inputs ที่ต้อง sync กับ state
- Real-time form validation
- Interactive controls
ทำไมต้องใช้:
- ✅ Two-way binding แท้จริง
- ✅ รองรับ input types ทั้งหมด
- ✅ มี modifiers ในตัว (lazy, number, trim)
- ✅ จัดการ type อัตโนมัติ
การใช้งานพื้นฐาน
Text Input
<input type="text" data-model="username">
<p>สวัสดี <span data-text="username"></span>!</p>เมื่อพิมพ์ ทั้งสองจะอัพเดทพร้อมกัน
ค่าเริ่มต้นจาก State
{
username: "สมชาย"
}<input type="text" data-model="username">
<!-- Input แสดง "สมชาย" ตอนเริ่ม -->Syntax
<input data-model="dataPath.modifier1.modifier2">| ส่วน | คำอธิบาย |
|---|---|
dataPath |
Path ไปยัง state property |
.modifier |
Modifiers ทางเลือก |
Input Types ที่รองรับ
Text Inputs
<input type="text" data-model="form.name">
<input type="email" data-model="form.email">
<input type="password" data-model="form.password">
<input type="tel" data-model="form.phone">
<input type="url" data-model="form.website">
<input type="search" data-model="searchQuery">Textarea
<textarea data-model="form.message"></textarea>Select
<select data-model="form.country">
<option value="">เลือก...</option>
<option value="th">ประเทศไทย</option>
<option value="us">สหรัฐอเมริกา</option>
</select>Multi-Select
<select multiple data-model="selectedItems">
<option value="a">ตัวเลือก A</option>
<option value="b">ตัวเลือก B</option>
<option value="c">ตัวเลือก C</option>
</select>State ได้รับ array: ["a", "c"]
Checkbox
<input type="checkbox" data-model="form.agreeTerms">State ได้รับ boolean: true หรือ false
Radio Buttons
<input type="radio" name="gender" value="male" data-model="form.gender">
<input type="radio" name="gender" value="female" data-model="form.gender">
<input type="radio" name="gender" value="other" data-model="form.gender">State ได้รับค่าที่เลือก: "male", "female", หรือ "other"
File Input
<input type="file" data-model="uploadedFiles">State ได้รับ FileList object
Number Input
<input type="number" data-model="form.quantity">
<input type="range" data-model="form.volume">Modifiers
.lazy
อัพเดทเมื่อ change event แทน input (เมื่อ input หมด focus):
<input type="text" data-model="search.lazy">เหมาะสำหรับ operations ที่แพงซึ่งไม่ควรทำงานทุก keystroke
.number
แปลงค่าเป็น number:
<input type="text" data-model="form.age.number">// ไม่มี .number: "25" (string)
// มี .number: 25 (number).trim
ตัด whitespace จากค่า:
<input type="text" data-model="form.name.trim">// Input: " สมชาย ใจดี "
// State: "สมชาย ใจดี"Combining Modifiers
<input type="text" data-model="form.amount.number.trim">ตัวอย่างขั้นสูง
ฟอร์มสมบูรณ์
<form data-form="registration">
<div class="form-group">
<label for="name">ชื่อ</label>
<input type="text" id="name" data-model="form.name.trim">
</div>
<div class="form-group">
<label for="email">อีเมล</label>
<input type="email" id="email" data-model="form.email.trim">
</div>
<div class="form-group">
<label for="age">อายุ</label>
<input type="number" id="age" data-model="form.age.number">
</div>
<div class="form-group">
<label for="country">ประเทศ</label>
<select id="country" data-model="form.country">
<option value="">เลือก...</option>
<option value="th">ประเทศไทย</option>
<option value="us">สหรัฐอเมริกา</option>
</select>
</div>
<div class="form-group">
<label>
<input type="checkbox" data-model="form.subscribe">
สมัครรับข่าวสาร
</label>
</div>
<button type="submit">ส่ง</button>
</form>Live Search
<div class="search-box">
<input type="text"
placeholder="ค้นหา..."
data-model="searchQuery">
<div data-if="searchQuery.length > 0">
<p>กำลังค้นหา: <span data-text="searchQuery"></span></p>
</div>
<div data-if="searchResults.length > 0" data-for="result in searchResults">
<template>
<div class="result" data-text="result.title"></div>
</template>
</div>
</div>แผงการตั้งค่า
<div class="settings">
<h3>การตั้งค่า</h3>
<label>
<input type="checkbox" data-model="settings.darkMode">
โหมดมืด
</label>
<label>
<input type="checkbox" data-model="settings.notifications">
เปิดการแจ้งเตือน
</label>
<label>
ระดับเสียง: <span data-text="settings.volume"></span>%
<input type="range"
min="0" max="100"
data-model="settings.volume.number">
</label>
<label>
ภาษา:
<select data-model="settings.language">
<option value="en">English</option>
<option value="th">ไทย</option>
</select>
</label>
</div>API อ้างอิง
State Updates
| Input Type | ค่าใน State |
|---|---|
| Text/Email/ฯลฯ | String |
| Number | String (ใช้ .number เพื่อได้ Number) |
| Checkbox | Boolean |
| Radio | ค่าที่เลือก (String) |
| Select | ค่าที่เลือก (String) |
| Select multiple | Array ของค่า |
| File | FileList object |
ข้อควรระวัง
⚠️ 1. Number Type โดยไม่มี Modifier
<!-- ❌ คืน string "25" -->
<input type="number" data-model="age">
<!-- ✅ คืน number 25 -->
<input type="number" data-model="age.number">⚠️ 2. Checkbox Initial State
// ❌ Undefined จะไม่ check/uncheck ถูกต้อง
{ agreeTerms: undefined }
// ✅ ใช้ boolean
{ agreeTerms: false }⚠️ 3. Select ไม่มี Empty Option
<!-- ❌ Option แรก auto-selected แต่ state อาจไม่ตรง -->
<select data-model="country">
<option value="th">ไทย</option>
<option value="us">USA</option>
</select>
<!-- ✅ เพิ่ม empty option สำหรับ initial state -->
<select data-model="country">
<option value="">เลือกประเทศ...</option>
<option value="th">ไทย</option>
<option value="us">USA</option>
</select>⚠️ 4. Nested Property Path
<!-- ❌ ถ้า form object ไม่มี -->
<input data-model="form.name">
<!-- ✅ Initialize nested object ก่อน -->
{
form: {
name: ""
}
}เปรียบเทียบ: data-model vs data-attr
| คุณสมบัติ | data-model | data-attr="value:..." |
|---|---|---|
| Two-way binding | ✅ ใช่ | ❌ One-way เท่านั้น |
| Input → State | ✅ ใช่ | ❌ ไม่ |
| Modifiers | .lazy, .number, .trim |
ไม่มี |
| Input types ทั้งหมด | ✅ ใช่ | พื้นฐานเท่านั้น |
Directives ที่เกี่ยวข้อง
- data-attr - สำหรับ one-way attribute binding
- data-checked - ทางเลือกสำหรับ checkboxes
- data-on - สำหรับ custom input handling