0

I have the problem, that I need to show an iframe within an Angular 6 app. This element should be present for all routes of a Module (lazy loaded). There are also other Modules in the app that don't need to show the iframe.

So a global solution like this could work but is not what I'm looking for:

<!-- app.component.html -->
<app-iframe></app-iframe>
<router-outlet></router-outlet>

Let's say the routing in this Module looks like this:

const routes: Routes = [
  {
    path: '',
    component: FirstComponent
  },
  {
    path: 'route-2',
    component: SecondComponent
  },
  {
    path: 'route-3',
    component: ThirdComponent
  }
];

Now in my module I can't simply create a component like IframeComponent and insert it into other components like:

<!-- first.component.html -->
<h1>Content of this component</h1>
<app-iframe></app-iframe>

This is because each time the another route of the module is loaded, the IframeComponent is reloaded and so is the actual iframe element.

I can't also cache the iframe DOM element in a Service, as the re-insertion will still trigger a reload. See: How to prevent an iframe from reloading when moving it in the DOM.

My question is:

How can I specify a Component that is rendered one time as long as the Module lives, no matter which router from this Module is called.

The result could look like this:

<router-outlet></router-outlet>
<app-first></app-first>
<app-iframe></app-iframe>

And after going to module-url/route-3:

<router-outlet></router-outlet>
<app-third></app-third> <!-- only this changed -->
<app-iframe></app-iframe>

And after going to another module:

<router-outlet></router-outlet>
<app-another-component></app-another-component>
lampshade
  • 2,470
  • 3
  • 36
  • 74

1 Answers1

0

Not 100% sure if I understand what you want, but you could have a component or a module with a component <my-iframe> and render it in app.component as a sibling to router-outlet: E.G:

<my-iframe></my-iframe>
<router-outlet></router-outlet>

My Iframe module has to be part of app.module of course. But now all dynamic content replaced by the router will have no effect on my-iframe

EDIT:

I understand it that way that you want to show/hide the iframe based on which component is rendered by the router. So you basically need to listen to router events to check which component is currently rendered and if you want to show your i-frame. I found a similar question on stackoverflow: Angular 2+: How to access active route outside router-outlet

There is a solution using routerevents, data in router config and a boolean observable to show/hide a sidebar (in your case the i-frame). Only thing is you should try to use [hidden]="!myVar" instead of ngIf, because otherwise the i-frame will reload again I guess.

J. S.
  • 2,268
  • 1
  • 12
  • 27
  • Thanks for your answer. This is close. But I don't want to have the `my-iframe`-component outside the Module where it is needed. There are other Modules that don't need that component. So basically I want a Component in a Module that is loaded one time while the Module is active, no matter, which route is activated. If this makes it more clear. – lampshade Jan 31 '19 at 14:26
  • When you have a module which only contains your `my-iframe` component and its dependencies then import it in app.modules it will only get loaded once. Other modules don't need to import it. – J. S. Jan 31 '19 at 14:50
  • I've rephrased the question - I hope it's a bit clearer now. Thanks. – lampshade Jan 31 '19 at 15:02
  • Ah thanks, that looks interesting - also thanks for the tip using `hidden`. I'll give it a try and get back to you with some results. Thanks. – lampshade Jan 31 '19 at 15:19