Root View and Controller is instantiated 2 times
See original GitHub issueOpenUI5 version: 1.44.15
Browser/version (+device/version): Google Chrome Version Version 61.0.3163.100 (Official Build) (64-bit) FAIL
Any other tested browsers/devices(OK/FAIL): Google Chrome Version 64.0.3249.0 (Official Build) canary (64-bit) FAIL
URL (minimal example if possible): com.gk-software.demo.nav-one-component.zip
User/password (if required and possible - do not post any confidential information here):
Steps to reproduce the problem: Please debug the example. Place breakpoint in ProcessBaseController, onInit() method. Start the example, onInit() is called 2 times before showing the view. In the DOM structure App is also present 2 times, specifically included in itself:
What is the expected result? In manifest.xml should be possible to define rootView and use it as a target. For example:
"sap.ui5": {
"_version": "1.1.0",
"rootView": "RootView",
...
"routes": [
{
"pattern": "component",
"name": "componentName",
"target": "component"
},
{
"pattern": "component/docs",
"name": "componentDocs",
"target": "componentDocs"
}],
"targets": {
"component": {
"viewName": "RootView",
"viewLevel" : 1
},
"componentDocs": {
"parent": "component",
"viewName": "Docs",
"transition": "show",
"viewLevel" : 2
}
}
What happens instead? When we use rootView as a target in manifest.xml, rootView and its controller are instantiated 2 times, there are 2 instances in the memory as well as in the DOM structure. Because of that we do not have possibility where to do things that should run only once during the lifecycle, i.e. in the onInit() method.
Any other information? (attach screenshot if possible)
The reason why it is happening is that in Component.js RootView is instantiated during component UIComponent.prototype.init.apply(this, arguments);
and then the Router matches the target with RootView and thus the second instance of RootView is created.
init: function () {
// call the init function of the parent
UIComponent.prototype.init.apply(this, arguments);
// create the views based on the url/hash
this.getRouter().initialize();
}
Is it possible to correct this behaviour and enable the possibility to use root view as a target?
Issue Analytics
- State:
- Created 6 years ago
- Comments:18 (8 by maintainers)
Hi @tanzhaus,
I put the answer first: “No, it’s not possible” and try to explain why it’s not possible.
Both “rootView” and “router” belong directly to the Component. “Router” and “rootView” don’t know about each other. The component builds up a connection between them by telling the router to use “rootView.byId(CONTROL_ID)” (CONTROL_ID is the routing configuration “controlId”) to find the container where the router places the target(s). Therefore the creation and instance management of the “rootView” isn’t in the scope of the router. When the rootView is configured as a routing target, another instance is created because router doesn’t know the existence of the rootView in the component and shouldn’t know about it.
However, there’s solution for the original problem. It can be solved by having a very simple rootView where only the container control is created. The View that should be shown with the empty hash “” should be declared as a target which is then displayed by the route with empty hash.
Best regards, Jiawei
Thank’s a lot Jiawei @stopcoder. Yes, creating a simple “root view” container works fine but some customer are not very happy about that due to increasing number of files and reorganizing existing hierarchies. Thanks to you I can now justify that 😃