Now.js Framework Documentation
Scope Isolation - การแยก Context ของข้อมูล
Scope Isolation - การแยก Context ของข้อมูล
ภาพรวม
เพื่อป้องกันความขัดแย้งเมื่อมีหลายระบบพยายาม process data-* directives เดียวกัน Now.js ใช้ระบบ Scope Isolation
ปัญหาที่แก้ไข
เมื่อมีระบบหลายตัวที่ทำงานกับ data-attr, data-text ฯลฯ พร้อมกัน:
<!-- ❌ ปัญหา: AppConfigManager และ FormManager ต่างก็พยายาม process data-attr="value:company" -->
<form data-load-api="/api/user/profile">
<input name="company" data-attr="value:company">
<!-- AppConfigManager: company = "Global Company" จาก API config -->
<!-- FormManager: company = "User Company" จาก API user profile -->
<!-- ผลลัพธ์: ค่าที่ได้ไม่แน่นอน ขึ้นกับระบบไหนทำงานทีหลัง -->
</form>วิธีแก้ไข: Automatic Scope Isolation
1. AppConfigManager จะ Skip Elements ใน Isolated Scopes
AppConfigManager จะไม่ process data-* directives ที่อยู่ภายใน:
✅ [data-component="api"] - ApiComponent
<div data-component="api" data-api-url="/api/products">
<span data-text="name">Product Name</span>
<!-- AppConfigManager จะไม่แตะ element นี้ -->
<!-- ApiComponent จัดการเอง -->
</div>✅ form[data-load-api] - FormManager with API Loading
<form data-load-api="/api/user/profile">
<input name="company" data-attr="value:company">
<!-- AppConfigManager จะไม่แตะ element นี้ -->
<!-- FormManager จัดการเอง -->
</form>✅ [data-load-api] - Any Container with API Loading
<div data-load-api="/api/dashboard/stats">
<span data-text="totalUsers">Loading...</span>
<!-- AppConfigManager จะไม่แตะ element นี้ -->
<!-- Container จัดการโหลดข้อมูลเอง -->
</div>2. AppConfigManager จะ Process เฉพาะ Global Elements
<!-- ✅ AppConfigManager WILL process these -->
<header>
<span data-text="company">My Company</span>
<img data-attr="src:logo" alt="Logo">
</header>
<footer>
<p data-text="copyright"></p>
<span data-text="version"></span>
</footer>แนวทางการใช้งาน
1. Global Configuration Data (AppConfigManager)
ใช้สำหรับข้อมูลที่แชร์ทั่วทั้ง application:
<nav>
<div class="brand">
<img data-attr="src:logo" alt="Logo">
<span data-text="company">Company Name</span>
</div>
</nav>
<footer>
<p data-text="copyright">© 2024 Company</p>
</footer>// API: /api/config
{
"company": "My Company Ltd.",
"logo": "/images/logo.png",
"copyright": "© 2024 My Company Ltd.",
"variables": {
"--color-primary": "#29336b"
}
}2. Form-Specific Data (FormManager)
ใช้สำหรับข้อมูลที่เฉพาะเจาะจงกับฟอร์ม:
<form data-load-api="/api/user/profile">
<input type="text" name="name" data-attr="value:name">
<input type="email" name="email" data-attr="value:email">
<select name="company_id" data-attr="value:company_id">
<!-- Options loaded from data-options-api -->
</select>
</form>// API: /api/user/profile
{
"data": {
"name": "John Doe",
"email": "john@example.com",
"company_id": "123"
}
}3. Component-Specific Data (ApiComponent)
ใช้สำหรับ components ที่โหลดข้อมูลเอง:
<div data-component="api" data-api-url="/api/products">
<div data-for="item in items">
<h3 data-text="item.name">Product</h3>
<p data-text="item.price">Price</p>
</div>
</div>Best Practices
✅ ถูกต้อง
<!-- Global config ใช้ AppConfigManager -->
<header>
<span data-text="siteName">Site Name</span>
</header>
<!-- Form data ใช้ FormManager -->
<form data-load-api="/api/user/profile">
<input name="username" data-attr="value:username">
</form>❌ ควรหลีกเลี่ยง
<!-- ไม่ควรใช้ชื่อเดียวกันใน global และ form scope -->
<header>
<span data-text="name">Global Name</span>
</header>
<form data-load-api="/api/user">
<input name="name" data-attr="value:name">
<!-- อาจสับสนว่า "name" มาจาก API ไหน -->
</form>Debug Mode
เปิด debug เพื่อดูว่า elements ไหนถูก skip:
Now.config.debug = true;Console จะแสดง:
[AppConfigManager] Skipped 5 elements in isolated scopes: [input, input, select, ...]การตรวจสอบ Scope
ใช้ helper method ตรวจสอบว่า element อยู่ใน isolated scope:
const element = document.querySelector('input[name="company"]');
const isIsolated = AppConfigManager.isInIsolatedScope(element);
console.log(isIsolated);
// true = อยู่ใน form[data-load-api] หรือ [data-component="api"]
// false = AppConfigManager จะ processสรุป
| Scope | Attribute | Managed By | Use Case |
|---|---|---|---|
| Global | ไม่มี | AppConfigManager |
ข้อมูลที่แชร์ทั่วทั้งแอป |
| Form | form[data-load-api] |
FormManager |
ข้อมูลฟอร์มเฉพาะ |
| Component | [data-component="api"] |
ApiComponent |
Component ที่โหลดข้อมูลเอง |
| Container | [data-load-api] |
Custom | Container ที่โหลดข้อมูลเอง |
หลักการ: แต่ละ scope จัดการข้อมูลของตัวเอง ไม่แทรกแซงกัน