- Description
- Recommended Approach
- How to configure project for decentralised events
- Custom client logic for events
- Centralized client logic:
- Example:
- The best way to structure your code in a workspace
Description
This article provides information on how best to write custom client logic for events and how to deploy distributed events.
Recommended Approach
- Once an object is loaded, the corresponding client logic file can be automatically generated in the workspace using the Events ribbon button.
- The generated file is treated like any other TypeScript source, the exposed functions are marked by exporting them.
- Once the client logic is implemented, the EventNamespace attribute must be filled with either a valid namespace (e.g. 'app.events') or the reserved encapsulation namespace '#'.
- This is done so that the runtime knows that the object will lazily load its client logic.
- In the context of "event namespace with lazy loading," events are organized within a specific namespace, and their associated functionality is loaded dynamically when triggered, optimizing resource usage. The use of "#" as a notation to denote functions within this namespace enhances clarity and facilitates a structured approach to handling events with lazy loading, contributing to more efficient and organized code.
- By using a valid namespace, the client logic is made available in the global context.
- Using the encapsulation namespace hides the logic from the global scope and only makes it available to the object at runtime.
- It is recommended to use the encapsulation parameter to keep the global context cleaner.
- With the namespace set, it is now possible to reference the functions in any case within the currently selected designer object (the object itself and its instances).
- If any menus are used (e.g. by ribbons, toolbars, ...) it will behave the same, the namespace references will map to the closest parent.
- When using a proper namespace, the events can be referenced either by the global scope (e.g. 'app.events.<objectname>.<function>') or by using the reserved 'eventNamespace' keyword (e.g. 'eventNamespace.<function>').
- When using the encapsulation namespace, the events can be referenced either by the 'eventNamespace' keyword or by the namespace itself (e.g. '#.<function>').
How to configure project for decentralised events
⚠️ As long as the project is based on the standard SWAT template, this step is not required, as everything is already set up by default.⚠️
Decentralised events will be independent of the main application bundle.
Each repository object referencing events will have its own bundle, which will be lazy-loaded at runtime.
The following directory structure is recommended:
webui
|-- client-logic
|-- _export
|-- <repository_object>.ts
|-- ...
|-- EventNamespaceDomain.ts
|-- ...
|-- ...
|-- index.ts
The EventNamespaceDomain.ts file is used by webpack to "know" that the files in the _export directory should be bundled in separate bundles.
And it will be used to register the namespace domain at runtime in index.ts.
Afterwards, any object added to the _export directory will be available for lazy-load at runtime.
The EventNamespaceDomain.ts file is used by webpack to "know" that the files in the _export directory should be bundled in separate bundles.
And it will be used to register the namespace domain at runtime in index.ts.
Afterwards, any object added to the _export directory will be available for lazy-load at runtime.
import EventNamespaceDomain from './client-logic/EventNamespaceDomain';
const eventNamespace = new EventNamespaceManager();
eventNamespace.registerDomain('APP', new EventNamespaceDomain());
export default {};
export default class EventNamespaceDomain {
async LoadEventNamespace(relativeFilePath: string) {
try {
const object = await import(
/* webpackChunkName: "[request]" */
`./_export/${relativeFilePath}`
);
return object;
} catch {
return null;
}
}
}
Custom client logic for events
Centralized client logic:
Most ui components allow users to run custom logic on certain events. (ex. on initialize, on value change, on before save, ...)
These customisable events are available directly from the repository as attributes.
The attributes support simple JavaScript/TypeScript syntax:
EventAttribute: '#.function(eventSource);'
Most of the time, the events will require access to the context of the event. (the object that is triggering the event, the screen, ...)
For that we introduced the following reserved keywords:
- eventSource - the object on which the event is triggered
- eventOrigin - the container from where the current screen was launched
The code implementation for centralized client logic is covered here:
Example:
Centralized events require the actual implementation to be part of the main bundle loaded on startup so that the functions are available in the global context.
With this approach, there are no constraints in terms of how the files are structured.
export default function helloWorld() {
console.log('Hello world!');
}
EventAttribute: '#.hellooWorld(eventSource);'
The best way to structure your code in a workspace
In order to structure the code in the best possible way, it should also correspond to the app in the folder structure.
If we have two apps, these should also be divided into different folder groups.
→ webui
|-- client-logic
|-- _export
|-- app A
|-- <repository_object>.ts
|-- app B
|-- <repository_object>.ts
How to use the different functions and access the objects is contained in the
Back to Documentation
Back to Home Page