Now.js Framework Documentation

Now.js Framework Documentation

Scope Isolation - การแยก Context ของข้อมูล

TH 12 Feb 2026 04:01

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 จัดการข้อมูลของตัวเอง ไม่แทรกแซงกัน