Bug or possibly poor design
When a tab is never opened, its contents should never be added to the DOM. This is how things worked with alpha 9 on Angular 2.0.1
Even if a tab is never opened, its content is added to the DOM before being removed.
This plunk shows the old behavior , from alpha 9. If you run the application while looking at network requests for images, you will see that only the image from the first tab is downloaded. To download another image, you need to open its tab.
This plunk shows the new behavior, from alpha 10. In this case, all images are downloaded immediately, then removed from the DOM.
In my use case, I have a menu on the first tab and a video on each of several other tabs. Since I upgraded to alpha 10, the browser fetches all the videos at once instead of waiting for the user to open a tab. This results in excessive bandwidth usage.
The same problem would occur for an app that has different image galleries organized by tab
Angular 2.1.2, Material 2 alpha 10 on Firefox 49
@andrewseguin I think this might be a bug in Angular based on the way we're doing tabs.
A dirty workaround: I listen to (selectChange) and I wrap the tab contents in an *ngIf that adds to the DOM only if the tab is currently selected.
It shouldn't load the content until the user click the tab.
I think the best approach is to load the content when the click event is fired and the loaded content is not destroyed anymore if the user switch to another tab and switch back again
Might be related: after upgrading to alpha.10
Tabs that have an *ngIf are breaking for me:
error_handler.js:47 EXCEPTION: Uncaught (in promise): TypeError: Cannot read property 'appendChild' of null
@esbeto my last demo (see my most recent post above) uses a working *ngIf within a tab
@RoxKilly There's something going on with Angular 2.2.0 and material tabs, that you can't use *ngIf in a tab, like so:
<md-tab *ngIf="expression">
</md-tab>
@esbeto Oh I see. I thought you meant:
<md-tab>
<div *ngIf="expression"> ... </div>
</md-tab>
Now I understand. It sounds like a separate issue from all tabs loading eagerly. In your shoes I would open a new issue and link to a demo of the problem.
The same error occurs when using *ngIf in a md-menu-item in combination with webpack.
<md-menu x-position="before" #menu="mdMenu">
<button *ngIf="expression" md-menu-item>Bewerken</button>
</md-menu>
EXCEPTION: Cannot read property 'appendChild' of null
@jelbourn did you have any more thoughts on this? As far as I can tell this bug was introduced with the Tabs API simplification in PR #1645. I have my own version of the tabs component(s) and just applied this change myself to try to fix the issue described in #573. It must be something to do with unwrapping the tab content from the <template> tags.
I reintroduced my equivalent of the md-tab-content directive to fix the issue in my own version.
Anyone knows when this will be fixed? In my case upgrading from alpha 9 is just impossible know. Every tab in my app contain a component that contains more nested components and it takes ages to render. Furthermore if I change tab every component in every tab is created and immediatelly destroyed. Components are using services to fetch data when initialized so for example: if I have 6 tabs and movefrom one to another I have 6 requests in network.
You can try to wrap contents of each tab with *ngIf="activeTabIndex=x"
@quanterion this workaround is difficult if you have some tabs which are *ngIf="user.hasRole('dkdk')" then the index is wrong if the tab is removed due the user settings
I had a notion that you can wrap tab content with an ngIf that checks if a tab has been activated at least once. I created a plunker that shows this: https://plnkr.co/edit/bzDrpGJGoYPI8NOdrgff?p=preview
The effect is lazy loading the content but I don't think the timing is right. I'd like the tab group to send an event _before_ changing the tab so that the framework has a chance to initialize the tab.
I'd like to look into this further and consider our options. I don't think native lazy loading will be possible since its the user's content that loads the content's components and sends them to the tab group. However I think we can provide enough information to the developer to correctly know when to show the content.
This is actually because of the way Angular does content project ( adheres to the web-components spec ). Content inside ng-content will always instantiate even if its not projected to the DOM. Material tabs uses content projection ( https://github.com/angular/material2/blob/master/src/lib/tabs/tab.html#L4 ) to create the content template of the tab and then projects it into the DOM when the tab is activated.
A temp workaround is to put the inner content in a div and do an *ngIf with an expression that is true when the selected tab is activated.
Reference: https://github.com/angular/angular/issues/13921#issuecomment-272557367
@amcdnl Funnily enough when I first filed an issue on this topic I referred to Material's Tabs implementation as a good reference for working around this issue. An older implementation of the Tabs did not have this issue, as mentioned above. It seems to have been introduced when the Tabs API was simplified in PR #1645 - reverting the underlying logic to what it was before this PR restores the lazy-loading behaviour.
@benelliott - We are working with the core team to fix this behavior. Stay tuned for updates :)
@andrewseguin What is the expected behavior of this when it is fixed?
Only active tab content is added to DOM? Or all tabs content are added?
Closing as tabs are no longer eagerly loaded. They are loaded when active and removed from the DOM otherwised.
@josephperrott
Not sure why this is closed, but the issue still present
https://stackblitz.com/edit/angular-6tqpal
UPDATE: figured out I have to use <ng-template matTabContent> and update example.
Use the event 'selectedIndexChange' on mat-tab-group and put your content in a div with ngIf,like this
https://stackblitz.com/edit/angular-tu7jsg
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
@benelliott - We are working with the core team to fix this behavior. Stay tuned for updates :)