Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
maheshpalavalli
Active Contributor
Sometime back (in 2016), I was exploring the component reuse for one of my project. Reusing the component was an easy task but I had trouble with the routing part of the reuse component (nested component), for which I had posted a question in SCN and at the end I didn't get a right answer, for which I had to resort to a workaround kind of solution.

In this blog I talk about the workaround that I used earlier and the easiest solution currently possible with ui5.

Qustion:

https://answers.sap.com/questions/12594180/loadinginstantiating-one-component-in-another-comp.html

The link I posted inside above question may not work. So I am giving the link below:

https://ui5.sap.com/1.44.35/#docs/guide/2c66fb3eb775426087401117cfa6a94e.html

Target Audience:


Should be having some good knowledge in UI5 especially in routing and will be more easier for those who knows component reuse.

Story:


Let me give the context of my then issue.

We were having 2 ui5 components (Child1, Child2). These components will be reused(loaded) inside Parent1 and Parent2 components.

Here Parent components have their own routing and Child components have their own routing. For these kind of scenarios, ui5 documentation has some information available but that flew right over my head 😄 😄 . So that is the reason of my above question.

Then Workaround:


I tried to do it the right way, but couldn't make it work and at the end I tried to solve it in a different way.

First in the child component(child1), I created routes without default pattern (""). Why I did this is that in my parent component we have default pattern and when ever that pattern is matched both the parent route handler and child route handler used to match 😄 . So i had to careful while designing the patterns and there shouldn't be any conflicts.

Child routing:
routes: [
{
pattern: "child1/{id}",
target: []
},
{
pattern: "child1/{id}/items",
target: []
}
]

Similarly, I've got another child component (child2) which has a similar routing. Observe, that I don't have a default pattern.

Now in my parent component, I loaded the child component but I didn't place it in the view immediately. I will only place it in the view when the route matches. If you guys are wondering how I loaded my child components, check these documentation:

https://ui5.sap.com/1.44.35/#docs/guide/346599f0890d4dfaaa11c6b4ffa96312.html

Parent component pattern:

It has it's own routing and also the replica of my child components pattern.
routes: [
{
pattern: "",
target: []
},
{
pattern: "child1/{id}",
target: ["child"]
},
{
pattern: "child1/{id}/items",
target: ["child"]
},
{
pattern: "child2/{id}",
target: ["child"]
},
{
pattern: "child2/{id}/items",
target: ["child"]
}
],
target:{
"child":{
"viewName": "DummyContainer"
}
}

Notice for all my child patterns there is single target. So when the pattern which is common in both the child and the parent is matched, then at both places routing will takes place.

Now every time a child route matches, my parent component child target will be called and in onInit function of the dummycontainer controller, I've registered for the routematched event and in that handler function, I will place the child components based on the matched route in the dummycontainer view.

So this workaround worked for me but the side effect is that I lost my child component default pattern, my parent component patterns shouldn't conflict with my child components pattern and I've to write some code manually in an IF condition to put my child components in the dummycontainer view based on the matched routes.

I still regret  that I didn't followed a standard way at that time. But hey it worked for me with a very less effort.

Now:


So I was just thinking about this recently and thought to check the documentation and now I see it has been changed with much more easy features and so I attempted again to do this the right way and it's a success this time 😛

The official documentation for enabling routing in the nested component.

https://ui5.sap.com/#/topic/fb19f501b16e4e4991eb6a017770945b.html

The documentation is pretty informative and can be easily understood.

For this, I've created 2 ui5 apps

  1. ZParentApp

  2. ZChildApp


So from the names we can understand that the ZChildApp component will be nested(loaded) inside the ZParentApp. So in my child app, I've the below routing configuration:
     "routes": [{
"name": "page1",
"pattern": "",
"target": ["page1"]
},{
"name": "page2",
"pattern": "Page2",
"target": ["page2"]
}],
"targets": {
"page1": {
"viewType": "XML",
"transition": "slide",
"clearControlAggregation": false,
"viewId": "Page1",
"viewName": "Page1"
},
"page2": {
"viewType": "XML",
"transition": "slide",
"clearControlAggregation": false,
"viewId": "Page2",
"viewName": "Page2"
}
}

Now this child app can be run individually without any issues. Let's go to the ZParentApp configurations.

Firstly, we need to define the component usage for the child app in the manifest.json
"sap.ui5": {
.......................................
"componentUsages": {
"childComp": { // Random name
"name": "child.ZChildApp", // namespace of the child app
"lazy": false
}
},

The above config will load the child component from the parent component. But we need to display the child component via routing, for which we need to maintain the below config in the routes:
	"routes": [{ // My parent routes
"name": "page1",
"pattern": "",
"target": ["page1"]
}, {
"name": "page2",
"pattern": "Page2",
"target": ["page2"]
}, { // This is the child route
"name": "childapp",
"pattern": "ChildPattern", // Dummy pattern
"target": [{
"name": "childapp",
// This prefix will be added to the url which the child route is matched
"prefix": "ChildPrefix"
}]
}],
"targets": {
"childapp": {
"type": "Component",
// SHould mention the component usage we defined earlier
"usage": "childComp"
},
"page1": {
"viewType": "XML",
"transition": "slide",
"clearControlAggregation": false,
"viewId": "Page1",
"viewName": "Page1"
},
"page2": {
"viewType": "XML",
"transition": "slide",
"clearControlAggregation": false,
"viewId": "Page2",
"viewName": "Page2"
}
}

 

Now if we call the "childpp" route, the child component is loaded. Then we can navigate inside the child view normally but this will effect the pattern in the url, which we will see in the below demo video.

Testing locally in webide without deployement:


For this to test, I didn't deploy the 2 apps to the launchpad, instead I used the latest features offered by webide to run this apps locally 🙂 🙂 You can check out the below blog on how to enable the App-to-App Navigation in webide.

https://blogs.sap.com/2018/03/05/fiori-app-to-app-navigation-in-web-ide-full-stack/

But it will still not work, as by default it works only for the hash based cross app navigation's. So for this we need to add the below code in neo-app.json file in the FLPSandbox project that is generated after you followed the steps in the above blog.
 {
"path": "/resources/child/ZChildApp", " Namespace of the component
"target": {
"type": "application",
"name": "zchildapp"
},
"description": "Navigate to zchildapp"
},

There you go, with that you can enable nested routing locally between 2 different ui5 apps.

Demo


Let's first see the child app running:



 

Now the parent app which loads the child app as a nested component via routing.



Let me know your thoughts on this 🙂

 

Update:


I just saw this openui5 YouTube video about how the fiori elements are built. It has a lot of details about component reuse via routing. Don't miss this out.

https://youtu.be/QK7hwDyNgq0

Thanks,

Mahesh
6 Comments
Labels in this area