#12 Where Your Own JavaScript Goes ​
Sooner or later an app needs something the XML view cannot express. A chart
library. A control nobody has wrapped. A UI5 method that exists only as a
method — sap.m.Carousel moves through setActivePage( ) and through nothing
else, and no property will do it for you.
This is the moment where frameworks usually grow a plugin system, and then a plugin registry, and then a page of documentation about lifecycle hooks. abap2UI5 has none of that, deliberately. It has three seams, each one a declared place rather than an escape hatch.
Three seams, from the cheapest to the widest: a method call by control id, an expression in the view, a custom control in its own BSP.
An imperative method needs no JavaScript at all. The client can call one on a control by id:
" t_arg is positional: control id, method, parameters
client->follow_up_action( val = z2ui5_if_client=>cs_event-control_by_id
t_arg = VALUE #( ( `myCarousel` )
( `setActivePage` )
( `page2` ) ) ).
The whitelist decides what is reachable. Check it before writing anything — a method it already declares costs one call, and an argument it does not declare is dropped in silence — a debugging session you can skip by reading a list first.
A custom control lives in its own BSP. The frontend resolves two reserved
resource roots — z2ui5_cci for the custom-controls addon, z2ui5_ccc for a
customer's own extension — so a control loads through the UI5 loader like any
other module, not as a string smuggled through a view.
A view attribute can compute. UI5 expression binding is available in an
app view — {= ${STATUS} === 'E' ? 'Error' : 'None' } — evaluated in the
browser against the model that just arrived, with no roundtrip and no module to
load. Write it as a backtick literal rather than a string template: a template
has to escape every brace, and one missed escape is a parser error on the whole
statement instead of a wrong string. Ask how we know.
Everything else is a system decision, not an app decision. Extra JavaScript
for the initial page is custom_js in the HTTP GET configuration, set in the
user exit through z2ui5_if_ui5_exit —
one place, reviewable, and the same for every app in the system.
None of them lets an app change the framework, and none requires the framework to change for an app. No plugin registry to learn, and no pull request to wait for either.
Extensibility is not the absence of a boundary. It is knowing exactly where the boundary is.