Now.js Framework Documentation
data-on-load
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);
}