Now.js Framework Documentation

Now.js Framework Documentation

data-on-load

TH 04 Apr 2026 13:04

data-on-load

ภาพรวม

data-on-load เรียกฟังก์ชัน global หลังคอนเทนต์พร้อมใช้งาน (เหมือน data-script) โดยจะเรียกเฉพาะบนอิลิเมนต์ที่มีแอตทริบิวต์นี้เอง และจะเกิดขึ้นก็ต่อเมื่อข้อมูลจาก API, ฟอร์ม หรือ submit-result binding ถูกแทรกลงใน DOM เสร็จเรียบร้อยแล้วเท่านั้น

ฟังก์ชันจะได้รับ TemplateManager context object เป็นอาร์กิวเมนต์ตัวที่สอง โดยใช้งานจริงดังนี้:

  • ใช้ context.state สำหรับ payload เต็มที่ถูก normalize แล้ว
  • ใช้ context.data สำหรับข้อมูลหลักที่ใช้แสดงรายการเมื่อมีค่า
  • สำหรับ declarative form result binding ค่า context.state จะมี schema กลาง และ context.data มักเป็น array ที่ใช้กับ data-for="item in data"

ใช้เมื่อ:

  • ต้องการ init หลายส่วนย่อยหลังข้อมูล API/ฟอร์มถูกใส่ลงใน container
  • ต้องการ attach behavior ที่อาศัยข้อมูลที่โหลดมา (เช่น สร้างแผนที่ กราฟ หรือ widget ภายนอก)
  • ใช้ signature (element, context) โดยที่ context.state คือ payload เต็ม และ context.data คือชุดข้อมูลหลักเมื่อมี

การใช้งานพื้นฐาน

<main>
  <section data-on-load="initFormLoad">
    <h2 data-text="data.title"></h2>
  </section>
</main>
function initFormLoad(element, context) {
  // element: DOM ที่มี data-on-load
  // context.state: payload เต็ม
  // context.data: ชุดข้อมูลหลักเมื่อมี
  console.log('init section', element, context.state, context.data);

  // cleanup (ถ้ามี)
  return () => {
    console.log('cleanup section');
  };
}

ทำงานอย่างไร

  • ApiComponent: หลังเรนเดอร์ข้อมูล (หรือดึงจาก cache) ApiComponent จะรัน [data-on-load] ทั้งหมดภายในคอมโพเนนต์ โดยส่ง render context เข้าไป
  • FormManager: หลังข้อมูลฟอร์มถูกโหลด หรือหลัง AJAX submit สำเร็จแล้ว bind result target ใหม่ FormManager จะรัน [data-on-load] ด้วย render context
  • TableManager: หากตารางโหลดข้อมูลจาก API แล้วเรนเดอร์เสร็จ จะเรียก [data-on-load] บนองค์ประกอบตารางเพียงครั้งเดียวหลังการเรนเดอร์

หมายเหตุเชิงปฏิบัติ: ในเวอร์ชันของ framework ล่าสุด data-on-load ยังคงเป็น hook หลักสำหรับการโหลดจาก API แต่ FormManager อาจเรียก data-on-load อีกกรณีหนึ่งเมื่อฟอร์มถูกสร้าง/แทรกเข้า DOM โดย ResponseHandler (เช่น ฟอร์มที่แสดงใน modal) และฟอร์มไม่มี data-load-api — ในกรณีนี้ FormManager จะเรียก data-on-load หนึ่งครั้งหลังการเริ่มต้นฟอร์ม โดยจะส่ง payload ที่ normalized ให้ (จะเลือก window._currentModalData เป็นลำดับแรกถ้ามี หรือใช้ค่าปัจจุบันของฟอร์มเป็นสำรอง)

เพื่อป้องกันการเรียกซ้ำ FormManager จะตั้ง flag ภายในตัว instance เมื่อมันเรียก data-on-load แล้ว ดังนั้น fallback call ขณะ init จะไม่ถูกเรียกอีกครั้งหากภายหลังฟอร์มได้รับข้อมูลจาก API จริงๆ

หมายเหตุ: data-on-load ใช้เฉพาะกับการโหลดจาก API หรือ payload ที่ถูกแทรกเข้ามาแล้วเท่านั้น สำหรับการรัน initialization ขณะนำทางหน้า (navigation) ให้ใช้ data-script ซึ่ง RouterManager จะเรียกในระหว่าง navigation — สอง hook นี้มีวัตถุประสงค์ต่างกันและไม่ควรถูกสับสนกัน

การใช้งานบน <body> (โดย AppConfigManager)

ในกรณีที่คุณกำหนด data-on-load บนแท็ก <body> เช่นเมื่อต้องการรัน logic หลังการโหลด config จาก backend, AppConfigManager จะเป็นตัวรันสคริปต์นี้ให้ และรูปแบบอาร์กิวเมนต์จะแตกต่างจากกรณีปกติ:

  • ปกติ (บนองค์ประกอบทั่วไป): handler จะถูกเรียกเป็น window[fn](element, context) — signature (element, context) ตามที่อธิบายไว้ข้างต้น
  • บน <body> (AppConfigManager): attribute จะถูกประมวลผลเป็นฟังก์ชันใหม่และเรียกเป็น fn(site, theme, config) — ส่งวัตถุ site (site metadata), theme (current theme string) และ config (รวม site, theme และ variables)

ตัวอย่างการใช้งานบน <body>:

<body data-on-load="document.title = site.title; initHeader(site, theme, config)">
  <!-- available: site, theme, config -->
</body>

ดูรายละเอียดเพิ่มเติมและตัวอย่างการใช้งานของ body-level data-on-load ในเอกสาร AppConfigManager (ไฟล์ docs/th/AppConfigManager.md).

รูปแบบฟังก์ชัน

function initFn(element, context) {
  // element: HTMLElement ที่มี data-on-load
  // context.state: payload เต็มแบบ TemplateManager
  // context.data: ชุดข้อมูลหลักเมื่อมี
  // คืนฟังก์ชัน cleanup ได้ (ถ้าต้องการ)
}
พารามิเตอร์ ชนิด คำอธิบาย
element HTMLElement อิลิเมนต์ที่มี data-on-load
context Object TemplateManager context. แนะนำให้ใช้ context.state สำหรับ payload เต็ม และ context.data สำหรับข้อมูลหลัก
คืนค่า ผลลัพธ์
undefined ไม่ทำ cleanup เพิ่มเติม
Function จะถูกเรียกเมื่อ cleanup (เช่น teardown ของ component/form)

Tips

  • ใช้ data-on-load กับหลายส่วนย่อย ส่วน data-script เหมาะกับ entry point เดี่ยว
  • เขียนฟังก์ชันให้ rerun ได้ (re-render อาจเกิดขึ้น)
  • คืน cleanup เพื่อลบ listener/interval เมื่อ teardown

ตัวอย่างกับผลลัพธ์การค้นหาแบบ declarative

<section id="results" data-on-load="initResults">
  <div data-for="item in data">
    <template>
      <article data-text="item.name"></article>
    </template>
  </div>
</section>
function initResults(element, context) {
  const rows = Array.isArray(context.data) ? context.data : [];
  const meta = context.state?.meta || {};
  console.log('rows:', rows.length, 'page:', meta.page);
}