loio |
---|
0cb44d7a147640a0890cefa5fd7c7f8e |
view on: demo kit nightly build | demo kit latest release
Since OpenUI5 1.125, the framework leverages features of modern ECMAScript, up to and including ES2023. You have to consider certain restrictions when using modern ECMAScript with your OpenUI5 project.
The restrictions described here apply to the usage of modern ECMAScript features in projects that are written in native JavaScript. If your project is written in TypeScript, you only have to make sure that the listed constraints are met by the transpiled code.
The following restrictions apply when you use modern ECMAScript:
-
Do not use ECMAScript modules, but use
sap.ui.define
/sap.ui.require
for module loading.For more information, see Defining and Loading OpenUI5 Modules.
-
Only use ES6+ classes for classes not deriving from OpenUI5 classes. When classes derive from OpenUI5 classes, do it the OpenUI5 way:
ClassName.extend()
.For more information, see OpenUI5 Inheritance.
-
Only use string literals (that is, no variables, no variable template literals, no spread parameter) for dependency names, class names, and library names.
For more information, see Defining and Loading OpenUI5 Modules (Expressions as Dependencies and following), OpenUI5 Inheritance (Expressions as Class Names and following), and Library Initialization.
-
Do not use async functions or Promises for defining a module.
For more information, see Asynchronous Factory Function in Defining and Loading OpenUI5 Modules.
-
Do not use async functions when implementing predefined lifecycle hooks, such as
sap/ui/core/mvc/Controller#onInit
.For more information, see Async Functions and Event Handlers.
OpenUI5 implements an AMD-like way of defining and loading modules. As Asynchronous Module Definition (AMD) is not fully compatible with ECMAScript modules, the use of ECMAScript modules is currently not supported.
OpenUI5 provides sap.ui.define
and sap.ui.require
as the established ways to define and load modules. Using the import
and export
statements for loading and defining OpenUI5 modules is currently not supported.
Please continue to use the regular OpenUI5 APIs sap.ui.define
and sap.ui.require
.
Supported usage
// Best practice of loading a module delivered by OpenUI5 sap.ui.define([ "sap/ui/core/mvc/Controller" ], (Controller) => { "use strict"; return Controller.extend("my.app.controller.MyController", {}); });
Not supported
// Do NOT use ECMAScript import and export statements when loading/defining OpenUI5 modules import Controller from "sap/ui/core/mvc/Controller"; export class MyController extends Controller {};
The OpenUI5 Loader will not wait for a Promise returned as the content of an OpenUI5 module.
While the usage of asynchronous factory functions and Promises as module content is not strictly forbidden, keep in mind that every Promise must be handled by the consumer of the module. An example of handy async factories is their use in top-level modules, like the framework's on-init
module.
However, do not use an async
factory function (or return a Promise) when defining OpenUI5 modules that contain entities of the following types, as they will not be awaited/chained in managed functionality, e.g. the processing of XMLView
s, the loading of Controller
s, etc.:
- Controls
- Components
- Typed views
- Fragments (JS)
- Controllers
- Controller extensions
- Data types
Component
s, TypedView
s, andFragment
s (JS) can still return Promises in an asynccreateContent
implementation; it is only their containing module that must not return a Promise as module content.
Example of an unsupported
Controller
module// Do NOT use the ECMAScript async/await statements when loading/defining modules sap.ui.define([ "sap/ui/core/mvc/Controller" ], async (Controller) => { "use strict"; return Controller.extend("my.app.controller.MyController", {}); });
Do not return a Promise when loading or defining OpenUI5 modules.
Example of an unsupported
Controller
module// Do NOT return a Promise when loading/defining modules sap.ui.define([ "sap/ui/core/mvc/Controller" ], (Controller) => { "use strict"; return Promise.resolve(Controller.extend("my.app.controller.MyController", {})); });
Use only literals but not expressions for the dependencies in the context of the sap.ui.define
and sap.ui.require
calls.
Not supported
// Do NOT use an expression in the list of dependencies // in an sap.ui.define or sap.ui.require call. const sController = "sap/ui/core/mvc/Controller"; sap.ui.define([ sController ], (Controller) => { });
Do not use a spread element as a parameter in the context of the sap.ui.define
and sap.ui.require
calls.
Not supported
// Do NOT use a spread element as a parameter // in an sap.ui.define or sap.ui.require call. const dependencies = [ "sap/ui/core/mvc/Controller", "sap/ui/mode/Filter", "sap/ui/model/FilterOperator", "sap/ui/model/json/JSONModel" ]; sap.ui.define([ ...dependencies ], (Controller, Filter, FilterOperator, JSONModel) => { });
The usage of template literals with one or more expressions in the context of the sap.ui.define
and sap.ui.require
calls is not supported.
Supported usage
// Using template literals without any expressions inside // an sap.ui.define or sap.ui.require call is supported sap.ui.define([ `sap/ui/core/mvc/Controller` ], (Controller) => { });
Not supported
// Do NOT use template literals with one or more // expressions inside an sap.ui.define or sap.ui.require call. const sLibName = `ui/core`; sap.ui.define([ `sap/${sLibName}/mvc/Controller` ], (Controller) => { });
Do NOT use async functions when implementing predefined OpenUI5 lifecycle hook methods. OpenUI5 might introduce an optional return type for such functions later. Using async functions here already would result in a return value that might conflict with such a later change.
Lifecycle hook methods should also refrain from returning a value in their implementation. The lifecycle hooks include the following methods:
Framework Class |
Lifecycle Hooks |
---|---|
|
|
|
|
|
|
|
|
Not supported
sap.ui.require(["sap/ui/core/mvc/Controller"], (Controller) => { return Controller.extend("my.controller.Sample", { // Do NOT use async event handlers for lifecycle hooks such as "onInit" or "onExit" onInit: async() => { await doSomething(); }, onExit: async() => { await doSomethingOnExit(); } }); });
You can implement an asynchronous event handler for control events. However, OpenUI5 directly invokes the event handler without taking into account the returned Promise or any execution order.
Supported usage
sap.ui.require(["sap/m/Button"], (Button) => { const oButton = new Button({ text: "Press me", press: async() => { // async "press" event handler await doSomethingAsync(); } }); });
Error Handling
Errors in asynchronous event handlers must be carefully managed. If you use an
await
inside an event handler and it throws an error, this typically won't be caught by the control that fired the event.
OpenUI5 implements an own functionality to extend classes (via the sap.ui.core.ManagedObject#extend
method). Using an ECMAScript class to extend a OpenUI5 class is currently not supported.
OpenUI5 uses its own way of defining classes and extending them. Please stick to the current best practice and do not use ECMAScript classes when extending a delivered OpenUI5 class.
Supported usage
// Best practice of extending an existing class delivered by OpenUI5 sap.ui.define(["sap/ui/core/mvc/Controller"], (Controller) => { "use strict"; return Controller.extend("my.app.controller.MyController", {}); });
Not supported
// Do not use ECMAScript classes when extending a delivered OpenUI5 class sap.ui.define(["sap/ui/core/mvc/Controller"], (Controller) => { "use strict"; return class MyController extends Controller {}; });
Do not use an expression, only a literal, in the class name parameter inside the extend
call.
Not supported
// Do NOT use an expression in the class name parameter inside the extend call const sControllerPath = "my.app.controller."; sap.ui.define([ "sap/ui/core/mvc/Controller" ], (Controller) => { "use strict"; return Controller.extend(sControllerPath + "MyController", {}); });
Do not use a variable as the class name parameter inside the extend
call.
Not supported
// Do NOT use a variable as a parameter inside the extend call const sController = "sap/ui/core/mvc/Controller"; sap.ui.define([ "sap/ui/core/mvc/Controller" ], (Controller) => { "use strict"; return Controller.extend(sController, {}); });
The usage of template literals with one or more expressions as the class name parameter inside the extend
call is not supported.
Supported usage
// Using template literals without any expressions inside the extend call sap.ui.define([ "sap/ui/core/mvc/Controller" ], (Controller) => { "use strict"; return Controller.extend(`my.app.controller.MyController`, {}); });
Not supported
// Do NOT use template literals with one or more expressions inside the extend call const sControllerPath = "my.app.controller."; sap.ui.define([ "sap/ui/core/mvc/Controller" ], (Controller) => { "use strict"; return Controller.extend(`${sControllerPath}MyController`, {}); });
An OpenUI5 library is typically initialized via an accompanying library.js
. Within that file, the object which is supplied to the sap/ui/core/Lib.init
method must consider the following restrictions:
Supported usage
// Best practice to initialize a library in the library.js file sap.ui.define([ "sap/ui/core/Lib" ], (Library) => { "use strict"; const thisLib = Library.init(({ apiVersion: 2, name: "my.lib", version: "${version}", designtime: "my/lib/designtime/library.designtime", types: [ "my.lib.MyType" ], interfaces: [ "my.lib.MyInterface" ], controls: [ "my.lib.MyType" ], elements: [ "my.lib.MyElement" ], extensions: {} }); });
Do not use an expression for the library name when initializing a library.
Not supported
// Do NOT use an expression for the library name when initializing a library const libraryName = "lib"; sap.ui.define([ "sap/ui/core/Lib" ], (Library) => { "use strict"; const thisLib = Library.init({ name: "my." + libraryName }); });
Do not use a variable for the library name when initializing a library.
Not supported
// Do NOT use a variable for the library name when initializing a library const key = "name"; sap.ui.define([ "sap/ui/core/Lib" ], (Library) => { "use strict"; const thisLib = Library.init({ [key]: "my.lib" }); });
Do not use a spread element for the library name when initializing a library.
Not supported
// Do NOT use a spread element for the library name when initializing a library const mylib = { name: "my.lib" }; sap.ui.define([ "sap/ui/core/Lib" ], (Library) => { "use strict"; const thisLib = Library.init({ ...mylib }); });
Do not use a template literal with one or more expressions for the library name when initializing a library.
Not supported
// Do NOT use a template literal with one or more expressions // for the library name when initializing a library const libraryName = "lib"; sap.ui.define([ "sap/ui/core/Lib" ], (Library) => { "use strict"; const thisLib = Library.init({ name: `my.${libraryName}` }); });
Related Information