docs/docs/en/runjs/context/on.md
Subscribe to context events in RunJS (e.g. field value change, property change, resource refresh). Events are mapped to custom DOM events on ctx.element or the internal event bus on ctx.resource.
| Scenario | Description |
|---|---|
| JSField / JSEditableField | Sync UI when field value changes from outside (form, linkage); two-way binding |
| JSBlock / JSItem / JSColumn | Listen to custom events on the container; react to data/state changes |
| resource | Listen to refresh, save, etc.; run logic after data updates |
on(eventName: string, handler: (event?: any) => void): void;
| Event | Description | Source |
|---|---|---|
js-field:value-change | Field value changed from outside (form linkage, default value) | CustomEvent on ctx.element; ev.detail = new value |
resource:refresh | Resource data refreshed | ctx.resource event bus |
resource:saved | Resource save completed | ctx.resource event bus |
Events with
resource:prefix usectx.resource.on; others typically use DOM events onctx.elementwhen present.
React.useEffect(() => {
const handler = (ev) => setValue(ev?.detail ?? '');
ctx.on?.('js-field:value-change', handler);
return () => {
ctx.off?.('js-field:value-change', handler);
};
}, []);
const handler = (ev) => {
if (selectEl) selectEl.value = String(ev?.detail ?? '');
};
ctx.element?.addEventListener('js-field:value-change', handler);
// Cleanup: ctx.element?.removeEventListener('js-field:value-change', handler);
ctx.resource?.on('refresh', () => {
const data = ctx.resource?.getData?.();
// Update render from data
});
ctx.off in useEffect cleanup.ctx.off may not exist; use optional chaining: ctx.off?.('eventName', handler).ctx.on(eventName, handler) should have a matching ctx.off(eventName, handler) with the same handler reference.on/offjs-field:value-change