-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(tabs): add ability to lazy load tab content #8921
Conversation
src/lib/tabs/tab.ts
Outdated
@@ -24,6 +24,7 @@ import { | |||
import {CanDisable, mixinDisabled} from '@angular/material/core'; | |||
import {Subject} from 'rxjs/Subject'; | |||
import {MatTabLabel} from './tab-label'; | |||
import { MdTabContent } from './tab-content'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No spaces between brackets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'd like @andrewseguin to take a look at this as well |
src/demo-app/tabs/tabs-demo.ts
Outdated
count = 0; | ||
ngOnInit() { | ||
this.count++; | ||
console.log('Counting...', this.count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you provide some comments about why we are console.log
ing and what the use of this Counter is?
src/demo-app/tabs/tabs-demo.html
Outdated
|
||
<h1>Lazy Loaded Tabs</h1> | ||
<mat-tab-group> | ||
<mat-tab label="First"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs consistent two-space indentation
@@ -80,6 +80,30 @@ The `tab-nav-bar` is not tied to any particular router; it works with normal `<a | |||
the `active` property to determine which tab is currently active. The corresponding | |||
`<router-outlet>` can be placed anywhere in the view. | |||
|
|||
## Lazy Loading | |||
By default, the tab contents are eagerly loaded. Eagerly loaded tabs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we mention here about how lazy-loading resolves issues with components that expect to be in the DOM while they setup? e.g. expansion panels and nested ink bars.
I suspect we'll want a place to point people to as we continue to get issues about this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preferably yes. I'm waiting on a fix to #5269, to render expansion panels within tabs....as are others.
I'll probably use lazy loading in combination with a the Progress Spinner component since I render many expansion panels within a tab (see EDIT view on JSONSchema.Net).
Eagerly awaiting this feature :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrewseguin - Added, let me know what u think?
src/lib/tabs/tab-content.ts
Outdated
|
||
import {Directive, TemplateRef} from '@angular/core'; | ||
|
||
@Directive({selector: '[matTabContent]'}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs some doc describing the use and purpose of this directive
src/lib/tabs/tab-content.ts
Outdated
import {Directive, TemplateRef} from '@angular/core'; | ||
|
||
@Directive({selector: '[matTabContent]'}) | ||
export class MdTabContent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MatTabContent
=P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some more MdTabContent
s lying around 😉
src/lib/tabs/tab-group.spec.ts
Outdated
let fixture = TestBed.createComponent(TemplateTabs); | ||
fixture.detectChanges(); | ||
|
||
let tabLabel = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to secondTabLabel
to make it more obvious what we are doing here
src/lib/tabs/tab.ts
Outdated
@@ -45,8 +46,11 @@ export class MatTab extends _MatTabMixinBase implements OnInit, CanDisable, OnCh | |||
/** Content for the tab label given by <ng-template mat-tab-label>. */ | |||
@ContentChild(MatTabLabel) templateLabel: MatTabLabel; | |||
|
|||
/** User provided template that we are going to use instead of implicitContent template */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Template provided in the tab content that will be used if present, used to enable lazy-loading"
src/lib/tabs/tabs.md
Outdated
declaring the body in a `ng-template` with the `matTabContent` attribute. | ||
|
||
```html | ||
<md-tab-group> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Md
or Mat
?
@andrewseguin - ready for round 2! |
@josephperrott - ready for merge. |
@andrewseguin this PR still needs your approval |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for your patience on the review. I'm excited to have this in as a solution for a lot of our issues open on tabs.
Add the merge ready
label once the comments are addressed. Just minor nits that shouldn't affect the actual logic
src/demo-app/tabs/tabs-demo.ts
Outdated
export class Counter { | ||
count = 0; | ||
ngOnInit() { | ||
this.count++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not totally sure what the count represents, shouldn't this be 1 for any component regardless of how it is loaded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, Its been so long I forgot what I was using it for too. I removed it.
src/lib/tabs/tabs.md
Outdated
|
||
If the tab contains several complex child components or the tab's contents | ||
rely on DOM calculations during initialization, it is advised | ||
to lazy load the tab's content. Tab contents can be lazy loaded by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this statement should stand out a bit more, even just by making it a new paragraph:
"Tab contents can be lazy loaded by declaring the body in a ng-template
with the matTabContent
attribute."
|
||
<h1>Lazy Loaded Tabs</h1> | ||
<mat-tab-group> | ||
<mat-tab label="First"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be neat to see a third tab that doesn't use lazy-loading so we can see the difference somehow (e.g. the content of Counter component should have the time it was loaded?)
This PR is a must for our application 👍 Will it make it for next version? |
@andrewseguin - resolved all comments. |
src/demo-app/tabs/tabs-demo.ts
Outdated
}) | ||
export class Counter { | ||
ngOnInit() { | ||
console.log('Tab Loaded:'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smallest nit ever: remove the colon ;)
src/demo-app/tabs/tabs-demo.ts
Outdated
@Component({ | ||
moduleId: module.id, | ||
selector: 'counter', | ||
template: `<span>{{count}}</span>` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
count
variable is not defined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@amcdnl this is a presubmit error in Google, so if you can fix that it should unblock moving forward
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
* feat(tabs): add ability to lazy load tab content * fix: lint * chore: nit * chore: pr feedback * fix: presubmit error
Just tried this out on the 6.0.0-beta-0 version. It seems to load the content as expected. The problem I'm having is that the content is being recreated every time you navigate to the tab. I've seen this exact behavior before when using a ng-template in combination with a *ngIf to toggle it. Seems like a similar situation here. I would want it to lazy load it when the tab is created, not when navigated to... |
I'd prefer to set that behaviour externally: something like a "creationPolicy" param with values like:
Best. |
@Marfyy and @aalbericio, the original issue (referring to #5269) was that to get animations to work inside a hidden tab some hacking was needed. IMO, this is fulfilled, as no hacking is necessary anymore. Maybe starting another issue asking to improve the lazy load feature is the best you can do now. This issue (again, referring to #5269) is likely to be closed as soon as 6.0.0 is officially released. |
Of course! That's more like a feature request. You're right! ;) |
agreed :) |
What version is this available in? Any 5.x.x versions or not until 6? |
Not until 6. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
This PR adds the ability to lazy load tabs, it is a new cut of #6832 on latest code.