Skip to content

Commit

Permalink
fix(theme): fix an issue when scrollbar didn't reset after a route ch…
Browse files Browse the repository at this point in the history
…ange (#91)
  • Loading branch information
lexzhukov authored Nov 28, 2017
1 parent 779a1a6 commit 9c77dad
Showing 1 changed file with 61 additions and 50 deletions.
111 changes: 61 additions & 50 deletions src/framework/theme/components/layout/layout.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,15 @@
*/

import {
AfterViewInit,
Component,
ComponentFactoryResolver,
ElementRef,
HostBinding,
HostListener,
Input,
OnDestroy,
Renderer2,
ViewChild,
ViewContainerRef,
AfterViewInit, Component, ComponentFactoryResolver, ElementRef, HostBinding, HostListener, Input, OnDestroy,
Renderer2, ViewChild, ViewContainerRef, OnInit,
} from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { Router, NavigationEnd } from '@angular/router';
import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/takeWhile';

import { convertToBoolProperty } from '../helpers';
import { NbThemeService } from '../../services/theme.service';
Expand Down Expand Up @@ -222,7 +214,7 @@ export class NbLayoutFooterComponent {
styleUrls: ['./layout.component.scss'],
template: `
<ng-template #layoutTopDynamicArea></ng-template>
<div class="scrollable-container">
<div class="scrollable-container" #scrollableContainer>
<div class="layout">
<ng-content select="nb-layout-header"></ng-content>
<div class="layout-container">
Expand All @@ -238,9 +230,10 @@ export class NbLayoutFooterComponent {
</div>
`,
})
export class NbLayoutComponent implements OnDestroy, AfterViewInit {
export class NbLayoutComponent implements AfterViewInit, OnInit, OnDestroy {

centerValue: boolean = false;

@HostBinding('class.window-mode') windowModeValue: boolean = false;
@HostBinding('class.with-scroll') withScrollValue: boolean = false;

Expand Down Expand Up @@ -286,57 +279,66 @@ export class NbLayoutComponent implements OnDestroy, AfterViewInit {
}

@ViewChild('layoutTopDynamicArea', { read: ViewContainerRef }) veryTopRef: ViewContainerRef;
@ViewChild('scrollableContainer', { read: ElementRef }) scrollableContainerRef: ElementRef;

protected afterViewInit$ = new BehaviorSubject(null);

protected appendClassSubscription: Subscription;
protected removeClassSubscription: Subscription;
protected themeSubscription: Subscription;
protected appendSubscription: Subscription;
protected clearSubscription: Subscription;

constructor(protected themeService: NbThemeService,
protected spinnerService: NbSpinnerService,
protected componentFactoryResolver: ComponentFactoryResolver,
protected elementRef: ElementRef,
protected renderer: Renderer2) {

this.themeSubscription = this.themeService.onThemeChange().subscribe((theme) => {

const body = document.getElementsByTagName('body')[0];
if (theme.previous) {
this.renderer.removeClass(body, `nb-theme-${theme.previous}`);
}
this.renderer.addClass(body, `nb-theme-${theme.name}`);
});
private alive: boolean = true;

constructor(
protected themeService: NbThemeService,
protected spinnerService: NbSpinnerService,
protected componentFactoryResolver: ComponentFactoryResolver,
protected elementRef: ElementRef,
protected renderer: Renderer2,
protected router: Router,
) {

this.themeService.onThemeChange()
.takeWhile(() => this.alive)
.subscribe((theme) => {
const body = document.getElementsByTagName('body')[0];
if (theme.previous) {
this.renderer.removeClass(body, `nb-theme-${theme.previous}`);
}
this.renderer.addClass(body, `nb-theme-${theme.name}`);
});

this.appendClassSubscription = this.themeService.onAppendLayoutClass().subscribe((className) => {
this.renderer.addClass(this.elementRef.nativeElement, className);
});
this.themeService.onAppendLayoutClass()
.takeWhile(() => this.alive)
.subscribe((className) => {
this.renderer.addClass(this.elementRef.nativeElement, className);
});

this.removeClassSubscription = this.themeService.onRemoveLayoutClass().subscribe((className) => {
this.renderer.removeClass(this.elementRef.nativeElement, className);
});
this.themeService.onRemoveLayoutClass()
.takeWhile(() => this.alive)
.subscribe((className) => {
this.renderer.removeClass(this.elementRef.nativeElement, className);
});

this.spinnerService.registerLoader(new Promise((resolve, reject) => {
this.afterViewInit$.subscribe((_) => resolve());
this.afterViewInit$
.takeWhile(() => this.alive)
.subscribe((_) => resolve());
}));
this.spinnerService.load();

// trigger first time so that after the change we have the initial value
this.themeService.changeWindowWidth(window.innerWidth);
}

ngAfterViewInit(): void {
this.appendSubscription = this.themeService.onAppendToTop()
ngAfterViewInit() {
this.themeService.onAppendToTop()
.takeWhile(() => this.alive)
.subscribe((data: { component: any, listener: Subject<any> }) => {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(data.component);
const componentRef = this.veryTopRef.createComponent(componentFactory);
data.listener.next(componentRef);
data.listener.complete();
});

this.clearSubscription = this.themeService.onClearLayoutTop()
this.themeService.onClearLayoutTop()
.takeWhile(() => this.alive)
.subscribe((data: { listener: Subject<any> }) => {
this.veryTopRef.clear();
data.listener.next(true);
Expand All @@ -345,17 +347,26 @@ export class NbLayoutComponent implements OnDestroy, AfterViewInit {
this.afterViewInit$.next(true);
}

ngOnDestroy(): void {
ngOnInit() {
this.initScrollTop();
}

ngOnDestroy() {
this.themeService.clearLayoutTop();
this.themeSubscription.unsubscribe();
this.appendClassSubscription.unsubscribe();
this.removeClassSubscription.unsubscribe();
this.appendSubscription.unsubscribe();
this.clearSubscription.unsubscribe();
this.alive = false;
}

@HostListener('window:resize', ['$event'])
onResize(event) {
this.themeService.changeWindowWidth(event.target.innerWidth);
}

private initScrollTop() {
this.router.events
.filter(event => event instanceof NavigationEnd)
.takeWhile(() => this.alive)
.subscribe(() => {
this.scrollableContainerRef.nativeElement.scrollTo && this.scrollableContainerRef.nativeElement.scrollTo(0, 0);
});
}
}

0 comments on commit 9c77dad

Please sign in to comment.