Bug/Regression from 2.0.0-beta.8.
Also a feature request for an API to allow triggering recalculations for the MdSidenavContainer/MdDrawerContainer, or being able to update _styles manually and having the view update..
In the previous release 2.0.0-beta.8 the sidenav resized when the window was resized.
I have a responsive sidenav that uses Angular flex-layout for showing/hiding responsive content in the sidenav when the view changes from md to lg and vice-versa.
In 2.0.0-beta.10 this is no longer the case. The changes made in #6189 made the sidenav update only when the sidenav is opening/closing.
Since flex-layout's changes occur without having to call open() or close() on the sidenav, the width recalculation doesn't occur.
Put dynamic/responsive content within a sidenav that is configured with "side".
Being able to dynamically call a refresh of the MdSidenav/MdDrawer or MdSidenavContainer/MdDrawerContainer.
Even better would be an accessor to allow manually setting the margin of the sidenav to allow for pre-computing the _style variable and updating it when needed.
Angular 4.3.5
Angular Material 2.0.0-beta.10
This is similar to #6583.
For right now I am using the following hack in my navigation directive to workaround whenever the ObservableMedia from angular flex-layout changes:
// Timeout required for flex-layout directives to update the child views/the width.
setTimeout(() => {
(this._container as any)._updateStyles();
(this._container as any)._changeDetectorRef.markForCheck();
}, 0);
+1. Same issue I have after upgrading to 2.0.0-beta.10
Same issue after upgrading from 2.0.0-beta.8 to 2.0.0-beta.10
My workarround :
app.component.html
<md-sidenav class="main-sidenav" #sidenav mode="side" opened="false">
app.component.ts
export class AppComponent implements AfterViewInit {
@ViewChild('sidenav')
private sidenav: MdSidenav;
ngAfterViewInit(): void {
setTimeout(() => {
this.sidenav.open();
}, 250);
}
}
that is exactly what i did @sbeaufort. It creates a small animation at the first page load but its ok
I have the exact same issue.
Here is my solution:
HTML
<md-sidenav-container #container>
<md-sidenav mode="side" opened="{{showMenu}}" class="shadow"></md-sidenav>
<div class="my-content"></div>
</md-sidenav-container>
TS
export class MyComponent implements OnInit, AfterViewInit {
@ViewChild('container') private _container;
public showMenu: boolean = false;
...
ngAfterViewInit() {
setTimeout(()=>{
this.showMenu = true;
},0);
this._container._ngZone.onMicrotaskEmpty.subscribe(() => {
this._container._updateStyles();
this._container._changeDetectorRef.markForCheck();
})
};
...
}
@ghwyf Thank you very much! This workaround also worked for me.
Same issue for me upgrading to 2.0.0-beta.10.
I used @ghwyf fix which works perfectly, thank you.
Closing as duplicate of #1130
Join the responses of @angularexample in #1130 and @ghwyf here, works for me.
_ngAfterViewInit_ seems too heavy for my application so I replace it with a specific call only when Subscription happens.
@josephperrott I think the issues are about different things. The one you referenced is about opening and closing the sidenav automatically when viewport width changes. This one is about being able to resize the sidenav width while keeping it open.
Before the last update this worked with no problem. Right now, the main content is not being resized when the sidebar width is resized. Some people have shared workarounds for this, but I think it would be nice if Angular Material would support this use case which is quite popular in places like firebase.
| Opened | Closed |
|-----|-----|
| | |
Reopening, sorry I misunderstood a bit there.
It would be really helpful to give a guide on this. Are we going to do this with animations? Will there be a function on the sidenav (like sidenav.resize(width))?
I am on the material2-builds and use the new fixedInViewport, which is great. But when I animate the sidenav from 220px to 75px the main content section does not adjust (as it used to before).
Any comments as to what we will expect here?
Same issue here.
After a while, I was forced to come back to 2.0.0-beta.8 when sidenav works perfect.
I would like to know if material team thinks this has to be fixed. If not, I will apply a workaround and stop waiting for a fix.
Thanks a lot!
Same problem here after upgrading to 2.0.0-beta.10 . The fix from @ghwyf doesn't work for me with angular 4.4.4
Here's my temporary workaround to fix it:
<md-sidenav-container #sideNavContainer>
<md-sidenav #sideNav align="start" mode="{{navMode}}" opened="true"
[@sideNavAnim] (@sideNavAnim.done)="onSideNavAnimDone($event)">
<!-- sidenav content -->
</md-sidenav>
<!-- primary content -->
<router-outlet *ngIf="sideNavAnimFinished"></router-outlet>
</md-sidenav-container>
export class MyComponent {
navMode = 'side';
sideNavAnimFinished = false;
...
onSideNavAnimDone(event) {
this.sideNavAnimFinished = true;
}
}
the example mentioned by @sbeaufort does not work well when the component has changeDetection: ChangeDetectionStrategy.OnPush
. In order to make it work you need to manually detect changes to the UI, example:
ngAfterViewInit(): void {
const size = this.drawerState === 'open' ? 220 : 75;
setTimeout(() => {
this.sidenav.open();
this.cd.detectChanges();
}, size);
}
@crisbeto is the resize function on a roadmap for sidenav?
Would it not suffice to add a "closeTo" option which, when in side mode and when set, does not transform to visibility hidden but sets the drawer width to whatever was closeTo was set to?
I was using @ghwyf workaround until beta.11 as well. What worked for me in beta.12 is the following:
export class MyComponent implements OnInit, AfterViewInit {
@ViewChild('container') private _container;
public showMenu: boolean = false;
...
ngAfterViewInit() {
setTimeout(()=>{
this.showMenu = true;
},0);
this._container._ngZone.onMicrotaskEmpty.subscribe(() => {
this._container._updateContentMargins();
this._container._changeDetectorRef.markForCheck();
})
};
...
}
@mpschaeuble this does not seem to work anymore:
Property '_ngZone' is private and only accessible within class 'MatDrawerContainer'.
@mmalerba is there anything you guys can give us here?
I definitely think we need to do something about this, even if its just making some of these methods public so people can trigger update manually. Raising the priority.
wow. it's like every month something new breaks. im stuck inbetween versions no., have to let the sidenav go broken. please fix this soon.
Problem still present in 5.0.0-rc0
@mmalerba
I think exposing a method to reflow the sizenav is reasonable, most component with on push should be able to reflow based on a users request.
That said, it's not developer friendly and verbose... nothing serious since a drawer is not used frequently in an app but still requires work.
From what I see, in most of the use cases the developer will set the width value of a sidenav which is easy since it's a user defined dom element...
If we create an @Input
for the width on sidenav we can automatically trigger the changes on the content element which is hidden from the developer.
This is automatic and does not require work from the dev.
The solution should be a public method + width input just in case
Working on a workaround I am getting more convinced that the MatDrawerContainer
needs to be notified by MatDrawer
when the MatDrawer
width property is changed.
Just exposing _updateContentMargins()
will not do.
Right now, calling _updateContentMargins()
on MatDrawerContainer
will query the width from the MatDrawer
(left or right). The width is taken from the DOM element directly by querying the native DOM element offsetWidth
property.
Simple animation transition in MatDrawer
will make the whole thing fail.
For example, we have MatDrawer
at 240px with 300ms transition and we change it to 60px and manually invoke _updateContentMargins()
.
When we call _updateContentMargins()
the width is probably 240px or something a bit smaller.
Or a redux scenario where the width of
MatDrawer
is bound to an observable on the template, when do we call_updateContentMargins()
?
Of course we can wait for animation to end but that is laggy, they should animate at the same time
Most workaround described above tackle the first render scenario
Same issue here with @angular/material": "5.0.0-rc0" with following settings
sidenavOpen: true,
sidenavMode: 'side',
sidenavCollapse: false,
@crisbeto thanks! Wonderful.
How does one achieve the minification of the sidenav now? Animations? Is there an example? Can I toggle to a certain width?
Thanks
@axtho what these changes do is allow you to opt in to having the drawer container resize once per change detection cycle, rather than on open/close.
@crisbeto so it is correct to assume that I would need to trigger change detection after running an animation when the component is on OnPush?
You _might_ not have to since the sidenav will check inside ngDoCheck
which keeps firing not matter the change detection strategy.
Still happening in 6.4.7:
"dependencies": {
"@angular/animations": "6.1.8",
"@angular/cdk": "^6.4.7",
"@angular/common": "6.1.8",
"@angular/compiler": "^6.1.8",
"@angular/core": "6.1.8",
"@angular/flex-layout": "^6.0.0-beta.18",
"@angular/forms": "^6.1.8",
"@angular/http": "6.1.8",
"@angular/material": "^6.4.7",
"@angular/platform-browser": "6.1.8",
"@angular/platform-browser-dynamic": "6.1.8",
"@angular/router": "6.1.8",
"@angular/service-worker": "6.1.8",
"@auth0/angular-jwt": "^2.0.0",
"@ngx-formly/core": "^4.7.2",
"@ngx-formly/material": "^4.7.2",
"@ngx-translate/core": "^10.0.2",
"@ngx-translate/http-loader": "^3.0.1",
"core-js": "^2.5.2",
"hammerjs": "^2.0.8",
"material-design-icons-iconfont": "^3.0.3",
"moment": "^2.22.1",
"rxjs": "^6.3.2",
"url": "^0.11.0",
"util": "^0.11.0",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.8.3",
"@angular/cli": "^6.2.3",
"@angular/compiler-cli": "^6.1.8",
"@angular/language-service": "6.1.8",
"@biesbjerg/ngx-translate-extract": "^2.3.1",
"@ngx-rocket/scripts": "^2.1.0",
"@types/jasmine": "^2.5.52",
"@types/jasminewd2": "^2.0.2",
"@types/lodash": "^4.14.103",
"@types/node": "^8.9.4",
"codelyzer": "^4.1.0",
"htmlhint": "^0.10.1",
"https-proxy-agent": "^2.0.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "^4.2.1",
"karma": "^3.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "^1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-junit-reporter": "^1.2.0",
"protractor": "^5.4.0",
"stylelint": "~9.1.1",
"stylelint-config-recommended-scss": "~3.1.0",
"stylelint-config-standard": "~18.2.0",
"stylelint-scss": "~2.5.0",
"ts-node": "~5.0.0",
"tslint": "~5.9.1",
"typescript": "^2.9.2"
}
Yep still an issue in 6.4.7
"@angular/material": "^6.4.7"
Come on, wheres the fix...?
Same. This is still an issue in 6.4.7
This solution is still a bit of a hack, but it's less of a hack than setTimeout...
@ViewChild('sidenavContainer') private sidenavContainer: MatSidenavContainer;
this.sidenavContainer._contentMarginChanges
.pipe(
debounceTime(250),
tap(() => this.sidenavContainer._contentMargins.left = this.sidenav._width),
)
.subscribe();
this.sidenavContainer.autosize = true;
worked for me... after mucking with it for an hour. :(
I observed the same issue in 6.4.7, but only in certain cases:
(line 713): this._ngZone.run(() => this._contentMargins.next({left, right}));
(line 717): this._ngZone.run(() => this._contentMarginChanges.next(this._contentMargins));
Finally I identified the buildOptimizer cache as the culprit. After deleting <project>/node_modules/@angular-devkit/build-optimizer/src/.cache
everything worked like a charm.
@dereekb this issue should not be closed.
Still exists in the year 2019.
@bobbydowling solution is the only thing worked for me. And I mucked with it for like 3 hours.
this.sidenavContainer.autosize = true;
worked for me... after mucking with it for an hour. :(
Where did you put autoSize = true ?
I have tried to put in OnInit() and AfterViewInit() but it didn't worked.
@MeghnathDas here is documentation of autosize
flag. It is option of mat-drawer-container
https://material.angular.io/components/sidenav/api#MatDrawerContainer
HTH
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
I definitely think we need to do something about this, even if its just making some of these methods public so people can trigger update manually. Raising the priority.