I have an Angular 7 application with which I want to use a Single Page GWT application as a component. The reason for using that GWT app as a component is that I don't want my GWT app to reload again and again whenever I navigate to that app (or page) using Angular routing.
Here's what I tried:
Firstly, I placed the compiled binaries of that GWT project in the assets folder of my Angular app. Then I put all the content under the tag of it's index.html in the component.html file of my Angular app. Then added a button and applied router navigation on it's click event so that clicking that button would navigate to my Angular app's component page.
I embed the GWT app in an iFrame in an Angular component. But I observed that while navigating to that page through routing, it was reloading again and again whenever I navigated back and forth to that page and to another Angular page using routing.
I also added the path of all the needed javascript files of GWT app in the scripts parameter in the angular.json file and modified allowJs parameter to true in tsconfig.json.
I know that when building the Angular project creates main.js file which contains the compiled JS code for all the components including their routing. So, I also thought of converting the main nocache.js file of GWT to the TS file, but it caused a lot of syntax errors, so I ignored this procedure.
Now with my limited knowledge, I can't think of any solutions except those specified above and I got really stuck at this situation and couldn't go ahead with my project.
So, can anyone please help me to find it's solution? I'm also not sure about whether it's possible to do this or not.
I'm adding another answer to address the issue mentioned in the comment of the first answer. The problem is that the iframe
inside a component still gets reloaded even if the component is kept alive by the RouteReuseStrategy. This is probably caused because Angular detaches it from the page DOM and then reattaches it.
One work around solution is to keep the component with the iframe
always alive inside your main application component and just hide it when you navigate to another page. Then show it again if you navigate to the route where you want to show it. You can do that by using Router events.
Here is a sample application component that implements this workaround. The gwt
component is the component with the iFrame.
The template:
<h2><a routerLink="/main">Main</a></h2>
<h2><a routerLink="/gwt">Gwt</a></h2>
<gwt [hidden]="!gwtVisible"></gwt>
<router-outlet [hidden]="gwtVisible"></router-outlet>
The code:
export class AppComponent {
gwtVisible = false;
constructor(router: Router) {
router.events.subscribe((routerEvent) => {
if (routerEvent instanceof NavigationEnd) {
this.gwtVisible = routerEvent.url === '/gwt';
}
});
}
}
As you can see from the code the application component hides the main content when you navigate to the /gwt
route and shows the gwt
component else it hides it and shows the other content normally from the router-outlet
.
In the routes I have defined that it navigates to an empty component just to have something for the route /gwt
.
const routes: Routes = [
{ path: '', redirectTo: 'main', pathMatch: 'full' },
{ path: 'main', component: MainComponent },
{ path: 'gwt', component: EmptyComponent }
];
I have created also a StackBlitz with a working sample.