SAPUI5 How To: Reuse parts of a SAPUI5 application in other/multiple SAPUI5 applications
Hi guys
This is something that I thought was going to be very complicated, turned out it was quite simple (if you know how).
Scenario:
So let’s say we have a bunch of code that we know we are going to use in multiple apps. In my case we have multiple apps that need supporting documents uploaded to DMS. So this piece of (not so small and very complicated) code appears in all the apps: Documents
Maintenance is a headache because you have to apply the same change to every app. So how can we include this Documents “fragment” in all of our other apps and only have to make changes to a single source that will reflect in all apps?
The answer: (choir of angels in the background) . . . . . Component Containers.
So what is a Component Container? According to saphelp:
“The ComponentContainer is a SAPUI5 control that contains a component and can be used at any place within the SAPUI5 control tree. The ComponentContainer separates the application and the embedded component. Technically, it uses a UIArea to avoid a nested control tree and to separate the eventing of the component’s user interface and the outer application. This separation ensures that the component is mostly self-contained and to avoid side effects from the outer application as well as the direct access via the control tree. In addition to this, a property on the ComponentContainer can be used to forward the model from the outer application into the embedded component.”
In english: It enables you to run one (or more) SAPUI5 application inside another SAPUI5 application, how cool is that?! I’m going to show you a simplified way of achieving this by using these Component Containers. You can read more here: Using UI Components in Applications
So lets start!
Create a new functioning app that only contains the part you need to reuse in your other apps. In my case, this is what my new app looks like:
And it’s fully functional:
So we have created our project as “EHSAttachments” and published the BSP to the ABAP server (Gateway).
Now I have created a 2nd app for demonstration purposes. We will run “EHSAttachments” inside this app: “TestReuse”
And then here comes the magic. Simply put the following line of code in your 2nd app’s (TestReuse) Component init function:
jQuery.sap.registerModulePath("ehsattachments", "../zehsattachments");
And in your second app’s view, simply do it by using the Component Container tag:
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" id="mainViewId" controllerName="testreuse.controller.Main" xmlns:html="http://www.w3.org/1999/xhtml">
<Page title="{i18n>appTitle}">
<content>
<core:ComponentContainer
name="ehsattachments"
manifestFirst= "true"
component="zehsattachments">
</core:ComponentContainer>
</content>
</Page>
</core:View>
And there you go!
Now the trick might come in when you have to start passing parameters between the 2 apps. This could be done by using “jQuery.sap.storage” to access variables stored in the default session storage. API: jQuery.sap.storage
For more info on reusing controls, check out Phillip’s blog: How to create a custom UI5 control
Antonette
你好,
我是一个新手,我们公司想要用你博客提到的方式开发,我有很多地方不清楚,请把源代码发我一份好吗,谢谢!
我的邮箱wwzhi2010@163.com
Hello,
I am a novice, our company would like to use your blog mentioned in the way of development, I have a lot of places are not clear, please send me a source code, thank you!
My mailbox wwzhi2010@163.com
hi Antonette,
Good that you are creating small pieces of re-usable code.. there are at least a few approaches to uses, and while there is absolutely nothing wrong with the approach you followed, I’d like to point out that all your “applications” (Components) are loaded under the same “Core”, so you can easily use the Core’s EventBus to subscribe & unsubscribe to events.
Make sure to use prefixes (perhaps your component namespace) so you don’t end up with clashes, pretty sure that will be more effective in terms of maintenance & in terms of performance over querying the storage with an interval function.
Cheers,
Dan.
Thanks for sharing Dan 🙂 I'll definitely use it
hi Antonette,
Thanks a lot for sharing this wonder ful concept, please let me know how the values are set, assume i have Invoice F4 help component being used in View2,
Now when i select a value from F4 Help , on click of ok how to set that value to input that is in veiw2.
Regards
Govardan
Hi Antonette,
Good to know this reusable stuff and great for you to blog it, however could you help to know how the same reusable stuff can be managed considering I have a router with a pattern for my first app and the same is required to be loaded(reused) in the 2nd app.
Regards,
Punith
Hello Punith
Could you please elaborate? And maybe give an example?
Regards
Antonette
Hi Antonette,
Firstly, thanks for the reply..,
Here it goes.., Let's say the calling component (EHSAttachments->in your case) has multiple view assigned with a pattern(route), if it needs to be reused in another app(TestReuse-> in your case) view, how to handle the scenario ?
Regards,
Punith
Hi Punith
That's a good question. I've only used this concept with simple controls instead of complete applications using a router so I don't know what the behaviour would be.
Please let us know what you find
Regards
Antonette
Thanks for sharing, Antonette. I think sharing via Component containers is very important yet it isn’t documented well or written about very often. Not only does your approach here save coding it also makes things easier for your users because the UI is entirely consistent.
If you use a slightly longer-form method (i.e. option 1 in the help you linked to) to instantiate the 1st component (e.g. the documents component) and then place it inside a container then of course you can call methods directly in that component. You can pass data that way.
If you do use the Core’s event bus as Daniel suggests be sure to unsubscribe your event handlers in the onExit method. They might not be destroyed automatically as they would be if you were using an Event bus which is attached to a single component.
I would also recommend, as Daniel does, that you are careful to avoid clashes between components. Don't name a view 'Main' or a model 'i18n'. Your references must be unique.
Thanks Mike. I'm also new to the component container concept so these were my first steps. I can't wait so see the amazing things coders will be able to achieve with this control. Thanks for sharing more insights. 🙂
Antonette
Hi,
according to the screenshots you used you were working in eclipse. I did something very similar a while ago developing in SAP Web IDE. Has anybody been able to get such a scenario running in the SAP Web IDE Fiori Testsandbox? When starting the "outer" application in the test sandbox it needs to load the "inner/reused" component. I tried everything I can imagine but I was not able to get this running. I always have to deploy to the ABAP Backend first and run it there. That is quite tedious if you just want to test a small change.
I actually found some links related to this like:
https://help.hana.ondemand.com/webide/frameset.htm?1114b927f5bc417e9a5912be40ee9ab8.html
and
https://help.sap.com/saphelp_nw74/helpdata/en/59/ea851d55e04c69a5ae07b15a3eda1b/content.htm
But couldn't get it working.
Regards
Tobias
Hi Tobias
Sorry for the late reply. I haven't worked with the fiori testsanbox before. Not sure if I understand you 100%, but I think you can try the first comment in this blog.
SAPUI5 How To: Create a custom library and how to use the JS files in other apps
Hope that is what you were looking for.
Antonette
Hi Tobias,
this blog may help you.
Regards Helmut
Hello Antonette ,
Thanks for the wonderful article. We are also trying to achieve similar thing. I have couple of doubts please help me out on them.
I understood that the first parameter is applicationName. Can you tell me how can i get the relative path "../zehsattachments"?
Hello Mihir
Thank you. 🙂
1 I haven't tried it on cloud before, please share you experience with us when you try.
2 the path is found here: "http://<gateway server>:<port>/sap/bc/ui5_ui5/sap/zehsattachments", you can browse for your app in tcode SICF by following the path above.
Hope this helps, good luck
Antonette
Thanks Antonette for the quick reply. We are having an issue with the path registration for the component - jQuery.sap.registerModulePath(“ehsattachments”, “../zehsattachments”);Can you please help us on this part.
We tried locating you in outlook but could not find you. Do you work for SAP? Please share your email address so that we can discuss more on it.
Hi Antonette,
thanks for the great blog. Works perfect. I'am currently trying out to get it running in SAP Cloud Platform.
BR,
Martin
Hi Martin,
were you able to run this in cloud platform?
Hi Antonette,
Thanks for the great blog. I have a small doubt.
jQuery.sap.registerModulePath(“ehsattachments”, “../zehsattachments”);
What are ehsattachments and zehsattachments in your case ? Are they the namespaces for Application 1 and 2 respectively ?
For Ex: The namespace for my first app is ABC and that of the second app is XYZ. So, shall I write like this:-
jQuery.sap.registerModulePath(“ABC”, “../XYZ”); ?
Thanks,
Souvik
Hi Souvik.
..... ("app1 namespace", "../app1 bsp name in abap system") ;
Hope this helps
Antonette
Hi Antonette,
very nice blog. I would like to use your re-use aproach in my UI5 project as well. But I was wondering what is the best way to refresh the data of a table in the component app (EHSAttachements), when a navigation from and to the view in the parent app (TestReuse) takes place.
Thanks for any hints.
Best regards
Dan
Hi,
First thanks.
Do I have to use Component.js file to reuse a part from another project?
In order to reuse the part, do I have to deploy to SAP Portal ?
Thanks.
Regards.
Hi Antonette ,
First thanks.
Do you have reuse the application :PLM_ATH_CRES1 ( Attachment Service Reusable)?
I Reuse this Component alway throw error:404 not Found!Do you have any way to solve this problem.
I have a lot of places are not clear about your blog, please send me a source code, thank you!
My mailbox :huangqin0813@163.com
Hi Antonette, I´m trying to create an app like yours, but the component of child app is being read from “<server>/sap/bc/zbsp_app/Component.js”, so no file is found.
I changed the app to use componentUsages in manifest.js of parent app, and the error persists. The child component is being read from “<server>/sap/bc/ui5_ui5/ui2/ushell/resources/~20180316143600~/NAME/SPACE/Component.js”
Any idea of how to read from
“<server>/sap/bc/ui5_ui5/sap/zbsp_app/~/Component.js” ?
the thread is https://answers.sap.com/questions/668485/ui5-failed-to-load-componentjs-while-using-compone.html
Update: problem solved registering full SICF path.
Hi Antonette,
How to handle OData service? The library(EHSAttachments)has itself OData?
Or, the library only responsible for the UI control(Fragment) and the consumer side will responsible for sending an "Add Document" OData request?
Thank you.
BRs,
Archer
hi Antonette,
Thanks a lot for sharing this wonderful concept, please let me know how the values are set, assume i have Invoice F4 help component being used in View2,
Now when i select a value from F4 Help , on click of ok how to set that value to input that is in veiw2.
Regards
Govardan
Hi Antonette Venter,
Thanks for the wonderful explanation of the Tricky Concept.
I have a requirement where there is a Fiori App having 4 Tabs. And want to bring a Custom TCODE UI in the 4th TAB.
Usually we provide a separate Tile on the Fiori Launchpad for Custom Tcodes, but here we want it as a Content of the TAB in an existing Fiori App.
Kindly let us know how can we achieve this.
Thanks & Regards:
Azhar
Hello @Antonette Venter,
I wished to use your solution on SAPUI5 V1.38.39 to get one application into my other application so in my component.js in init I used :
And in my view :
But I get the error
Do you know how to solve it ?
Thanks and regards,
Sylvain
I have the same problem with SAP Web IDE, did you find a solution?
Thanks.
Hi Antonette,
thanks a lot for your excellent blog.
I was able to embed one child SAP Fiori element list report with the ComponentContainer without issue.
I have a requirement to embed the same child SAP Fiori element list report twice in the same parent app (split screen).
I'm receiving an "Duplicate ID error:
2021-06-22 08:09:10.282300 adding element with duplicate id 'myChildApp::sap.suite.ui.generic.template.ListReport.view.ListReport::myChildApp--template::PageVariant' -
Do you have any idea how to handle this issue?
Thanks a lot in advance.
Kind regards
Axel
Antonette Venter , is it possible to do this if the 2 apps are using 2 different odata services?