I'm trying to create a base controller that has common methods and common onInit
logic.
Using the extend
method adds the methods from the base controller to the child controller, but the lifecycle methods get overwritten completely.
override.onInit
approach shown on this documentation page but it did not work.sap.ui.component
like this but I couldn't get it to work at all.As far as I understood, the extension feature should replace common methods that have been overridden, but it should execute the lifecycle methods from both the base and extension controller on this respective order.
So my question are the following:
Example code:
Parent controller
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("my.namespace.controller.App", {
onInit: function () {
console.log("reusable init");
},
// ...
});
});
Child controller
sap.ui.define([
"my/namespace/controller/App.controller"
], function (Controller) {
"use strict";
return Controller.extend("my.namespace.child.controller.App", {
onInit: function () {
console.log("extend init");
},
// ...
});
});
This example logs only "extend init" when I run the application. I expected it to log both "reusable init" and "extend init" in this order.
I've omitted some code, but the main idea is represented on these two controllers. The only relevant metadata is that the base controller is abstract.
In many cases, when developing applications from scratch, the BaseController approach is sufficient as Benedikt explained, or you could try composition with many tiny modules, depending on your project.
The topic controller extension is lesser-known, yet worth to get to know what it's about and how extensions can also help us in application development. The documentation does hint that the extension concepts usually target developers who want to extend existing applications with additional features. However, extensions can also be used:
[...] as a reusable part that is added to the original application. (Source)
Currently, there are two main approaches:
The older concept Component Configuration
Extensions are declared in manifest.json
(or formerly in Component.js
) and return a plain object {}
.
[...] Only one level of controller extension is allowed; nested controller extension is not supported. (Source)
Example: embed.plnkr.co/7jnWdezkHueq3esS
The newer concept Controller Extension
Defines methods
metadata and the extension returns a sap.ui.core.mvc.ControllerExtension
with overrides
.
manifest.json
(same as above) or added as dependency to your own application development as reusable parts.public: true | false
(default: true
)final: true | false
(default: false
)overrideExecution: "After" | "Before" | "Instead"
(default: "Instead"
)this.base
from the extension (Extensions of SAP Fiori elements apps should call this.base.getExtensionAPI()
).Example: embed.plnkr.co/xnVMDtx8f2IgI91A
In either case, UI5 executes the lifecycle methods in the following order by default:
Execution order | Original controller code | Extension code |
---|---|---|
1. | onInit |
|
2. | onInit |
|
3. | onBeforeRendering |
|
4. | onBeforeRendering |
|
5. | onAfterRendering |
|
6. | onAfterRendering |
|
7. | onExit |
|
8. | onExit |