Skip to content

Commit

Permalink
feat: support server-side rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
hsuanxyz committed Apr 18, 2019
1 parent 82407e7 commit 1cb86f2
Show file tree
Hide file tree
Showing 16 changed files with 157 additions and 94 deletions.
50 changes: 34 additions & 16 deletions components/affix/nz-affix.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Platform } from '@angular/cdk/platform';
import { DOCUMENT } from '@angular/common';
import {
ChangeDetectionStrategy,
Expand Down Expand Up @@ -35,10 +36,12 @@ import { throttleByAnimationFrameDecorator } from '../core/util/throttleByAnimat
export class NzAffixComponent implements OnInit, OnDestroy {
@Input()
set nzTarget(value: string | Element | Window) {
this.clearEventListeners();
this._target = typeof value === 'string' ? this.doc.querySelector(value) : value || window;
this.setTargetEventListeners();
this.updatePosition({} as Event);
if (this.platform.isBrowser) {
this.clearEventListeners();
this._target = typeof value === 'string' ? this.doc.querySelector(value) : value || window;
this.setTargetEventListeners();
this.updatePosition({} as Event);
}
}

@Input()
Expand Down Expand Up @@ -73,13 +76,21 @@ export class NzAffixComponent implements OnInit, OnDestroy {

private affixStyle: NGStyleInterface | undefined;
private placeholderStyle: NGStyleInterface | undefined;
private _target: Element | Window = window;
private _target: Element | Window | null = null;
private _offsetTop: number | null;
private _offsetBottom: number | null;

// tslint:disable-next-line:no-any
constructor(_el: ElementRef, private scrollSrv: NzScrollService, @Inject(DOCUMENT) private doc: any) {
constructor(
_el: ElementRef,
private scrollSrv: NzScrollService,
@Inject(DOCUMENT) private doc: any,
private platform: Platform
) {
this.placeholderNode = _el.nativeElement;
if (this.platform.isBrowser) {
this._target = window;
}
}

ngOnInit(): void {
Expand Down Expand Up @@ -125,15 +136,19 @@ export class NzAffixComponent implements OnInit, OnDestroy {

private setTargetEventListeners(): void {
this.clearEventListeners();
this.events.forEach((eventName: string) => {
this._target.addEventListener(eventName, this.updatePosition, false);
});
if (this.platform.isBrowser) {
this.events.forEach((eventName: string) => {
this._target!.addEventListener(eventName, this.updatePosition, false);
});
}
}

private clearEventListeners(): void {
this.events.forEach(eventName => {
this._target.removeEventListener(eventName, this.updatePosition, false);
});
if (this.platform.isBrowser) {
this.events.forEach(eventName => {
this._target!.removeEventListener(eventName, this.updatePosition, false);
});
}
}

private getTargetRect(target: Element | Window | undefined): ClientRect {
Expand Down Expand Up @@ -205,11 +220,14 @@ export class NzAffixComponent implements OnInit, OnDestroy {

@throttleByAnimationFrameDecorator()
updatePosition(e: Event): void {
const targetNode = this._target;
if (!this.platform.isBrowser) {
return;
}
const targetNode = this._target as (HTMLElement | Window);
// Backwards support
let offsetTop = this.nzOffsetTop;
const scrollTop = this.scrollSrv.getScroll(targetNode, true);
const elemOffset = this.getOffset(this.placeholderNode, targetNode);
const scrollTop = this.scrollSrv.getScroll(targetNode!, true);
const elemOffset = this.getOffset(this.placeholderNode, targetNode!);
const fixedNode = this.fixedEl.nativeElement as HTMLElement;
const elemSize = {
width: fixedNode.offsetWidth,
Expand All @@ -227,7 +245,7 @@ export class NzAffixComponent implements OnInit, OnDestroy {
offsetMode.top = typeof offsetTop === 'number';
offsetMode.bottom = typeof this._offsetBottom === 'number';
}
const targetRect = this.getTargetRect(targetNode);
const targetRect = this.getTargetRect(targetNode as Window);
const targetInnerHeight = (targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight;
if (scrollTop >= elemOffset.top - (offsetTop as number) && offsetMode.top) {
const width = elemOffset.width;
Expand Down
6 changes: 5 additions & 1 deletion components/anchor/nz-anchor-link.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Platform } from '@angular/cdk/platform';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Expand Down Expand Up @@ -54,6 +55,7 @@ export class NzAnchorLinkComponent implements OnInit, OnDestroy {
public elementRef: ElementRef,
private anchorComp: NzAnchorComponent,
private cdr: ChangeDetectorRef,
private platform: Platform,
renderer: Renderer2
) {
renderer.addClass(elementRef.nativeElement, 'ant-anchor-link');
Expand All @@ -66,7 +68,9 @@ export class NzAnchorLinkComponent implements OnInit, OnDestroy {
goToClick(e: Event): void {
e.preventDefault();
e.stopPropagation();
this.anchorComp.handleScrollTo(this);
if (this.platform.isBrowser) {
this.anchorComp.handleScrollTo(this);
}
}

markForCheck(): void {
Expand Down
13 changes: 11 additions & 2 deletions components/anchor/nz-anchor.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Platform } from '@angular/cdk/platform';
import { DOCUMENT } from '@angular/common';
import {
AfterViewInit,
Expand Down Expand Up @@ -74,8 +75,13 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit {
private scroll$: Subscription | null = null;
private destroyed = false;

/* tslint:disable-next-line:no-any */
constructor(private scrollSrv: NzScrollService, @Inject(DOCUMENT) private doc: any, private cdr: ChangeDetectorRef) {}
constructor(
private scrollSrv: NzScrollService,
/* tslint:disable-next-line:no-any */
@Inject(DOCUMENT) private doc: any,
private cdr: ChangeDetectorRef,
private platform: Platform
) {}

registerLink(link: NzAnchorLinkComponent): void {
this.links.push(link);
Expand All @@ -99,6 +105,9 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit {
}

private registerScrollEvent(): void {
if (!this.platform.isBrowser) {
return;
}
this.removeListen();
this.scroll$ = fromEvent(this.getTarget(), 'scroll')
.pipe(
Expand Down
12 changes: 8 additions & 4 deletions components/avatar/nz-avatar.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Platform } from '@angular/cdk/platform';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Expand Down Expand Up @@ -52,7 +53,8 @@ export class NzAvatarComponent implements OnChanges {
private elementRef: ElementRef,
private cd: ChangeDetectorRef,
private updateHostClassService: NzUpdateHostClassService,
private renderer: Renderer2
private renderer: Renderer2,
private platform: Platform
) {}

setClass(): this {
Expand Down Expand Up @@ -114,9 +116,11 @@ export class NzAvatarComponent implements OnChanges {

private notifyCalc(): this {
// If use ngAfterViewChecked, always demands more computations, so......
setTimeout(() => {
this.calcStringSize();
});
if (this.platform.isBrowser) {
setTimeout(() => {
this.calcStringSize();
});
}
return this;
}

Expand Down
11 changes: 10 additions & 1 deletion components/back-top/nz-back-top.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Platform } from '@angular/cdk/platform';
import { DOCUMENT } from '@angular/common';
import {
ChangeDetectionStrategy,
Expand Down Expand Up @@ -56,7 +57,12 @@ export class NzBackTopComponent implements OnInit, OnDestroy {
@Output() readonly nzClick: EventEmitter<boolean> = new EventEmitter();

// tslint:disable-next-line:no-any
constructor(private scrollSrv: NzScrollService, @Inject(DOCUMENT) private doc: any, private cd: ChangeDetectorRef) {}
constructor(
private scrollSrv: NzScrollService,
@Inject(DOCUMENT) private doc: any,
private platform: Platform,
private cd: ChangeDetectorRef
) {}

ngOnInit(): void {
if (!this.scroll$) {
Expand Down Expand Up @@ -88,6 +94,9 @@ export class NzBackTopComponent implements OnInit, OnDestroy {
}

private registerScrollEvent(): void {
if (!this.platform.isBrowser) {
return;
}
this.removeListen();
this.handleScroll();
this.scroll$ = fromEvent(this.getTarget(), 'scroll')
Expand Down
44 changes: 26 additions & 18 deletions components/carousel/nz-carousel.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { LEFT_ARROW, RIGHT_ARROW } from '@angular/cdk/keycodes';
import { Platform } from '@angular/cdk/platform';
import {
AfterContentInit,
AfterViewInit,
Expand Down Expand Up @@ -99,7 +100,8 @@ export class NzCarouselComponent implements AfterViewInit, AfterContentInit, OnD
public elementRef: ElementRef,
private renderer: Renderer2,
private cdr: ChangeDetectorRef,
private ngZone: NgZone
private ngZone: NgZone,
private platform: Platform
) {
renderer.addClass(elementRef.nativeElement, 'ant-carousel');
}
Expand All @@ -118,16 +120,18 @@ export class NzCarouselComponent implements AfterViewInit, AfterContentInit, OnD
})
);

this.ngZone.runOutsideAngular(() => {
this.subs_.add(
fromEvent(window, 'resize')
.pipe(debounceTime(50))
.subscribe(() => {
this.renderContent();
this.setTransition();
})
);
});
if (this.platform.isBrowser) {
this.ngZone.runOutsideAngular(() => {
this.subs_.add(
fromEvent(window, 'resize')
.pipe(debounceTime(50))
.subscribe(() => {
this.renderContent();
this.setTransition();
})
);
});
}

// When used in modals (drawers maybe too), it should render itself asynchronously.
// Refer to https://github.com/NG-ZORRO/ng-zorro-antd/issues/2387
Expand Down Expand Up @@ -158,8 +162,10 @@ export class NzCarouselComponent implements AfterViewInit, AfterContentInit, OnD
this.slideContents.forEach((slide, i) => (slide.isActive = index === i));
this.setUpNextScroll();
this.cdr.markForCheck();
// Should trigger the following when animation is done. The transition takes 0.5 seconds according to the CSS.
setTimeout(() => this.nzAfterChange.emit(index), this.nzTransitionSpeed);
if (this.platform.isBrowser) {
// Should trigger the following when animation is done. The transition takes 0.5 seconds according to the CSS.
setTimeout(() => this.nzAfterChange.emit(index), this.nzTransitionSpeed);
}
}
}

Expand Down Expand Up @@ -250,11 +256,13 @@ export class NzCarouselComponent implements AfterViewInit, AfterContentInit, OnD
* Make a carousel scroll to `this.nextIndex` after `this.nzAutoPlaySpeed` milliseconds.
*/
private setUpNextScroll(): void {
this.clearTimeout();
if (this.nzAutoPlay && this.nzAutoPlaySpeed > 0) {
this.transitionAction = setTimeout(() => {
this.setContentActive(this.nextIndex);
}, this.nzAutoPlaySpeed);
if (this.platform.isBrowser) {
this.clearTimeout();
if (this.nzAutoPlay && this.nzAutoPlaySpeed > 0) {
this.transitionAction = setTimeout(() => {
this.setContentActive(this.nextIndex);
}, this.nzAutoPlaySpeed);
}
}
}

Expand Down
24 changes: 16 additions & 8 deletions components/icon/nz-icon.directive.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Platform } from '@angular/cdk/platform';
import {
AfterContentChecked,
Directive,
Expand Down Expand Up @@ -170,7 +171,12 @@ export class NzIconDirective extends IconDirective implements OnInit, OnChanges,
}
}

constructor(public iconService: NzIconService, public elementRef: ElementRef, public renderer: Renderer2) {
constructor(
public iconService: NzIconService,
public elementRef: ElementRef,
public renderer: Renderer2,
private platform: Platform
) {
super(iconService, elementRef, renderer);
}

Expand All @@ -192,13 +198,15 @@ export class NzIconDirective extends IconDirective implements OnInit, OnChanges,
this.iconService.warnAPI('old');
// Get `type` from `className`. If not, initial rendering would be missed.
this.classChangeHandler(this.el.className);
// Add `class` mutation observer.
this.classNameObserver = new MutationObserver((mutations: MutationRecord[]) => {
mutations
.filter((mutation: MutationRecord) => mutation.attributeName === 'class')
.forEach((mutation: MutationRecord) => this.classChangeHandler((mutation.target as HTMLElement).className));
});
this.classNameObserver.observe(this.el, { attributes: true });
if (this.platform.isBrowser) {
// Add `class` mutation observer.
this.classNameObserver = new MutationObserver((mutations: MutationRecord[]) => {
mutations
.filter((mutation: MutationRecord) => mutation.attributeName === 'class')
.forEach((mutation: MutationRecord) => this.classChangeHandler((mutation.target as HTMLElement).className));
});
this.classNameObserver.observe(this.el, { attributes: true });
}
}
// If `classList` does not contain `anticon`, add it before other class names.
if (!this.el.classList.contains('anticon')) {
Expand Down
4 changes: 3 additions & 1 deletion components/menu/nz-submenu.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CdkConnectedOverlay, CdkOverlayOrigin, ConnectedOverlayPositionChange } from '@angular/cdk/overlay';
import { Platform } from '@angular/cdk/platform';
import {
AfterContentInit,
ChangeDetectionStrategy,
Expand Down Expand Up @@ -100,7 +101,7 @@ export class NzSubMenuComponent implements OnInit, OnDestroy, AfterContentInit,
}

setTriggerWidth(): void {
if (this.nzSubmenuService.mode === 'horizontal') {
if (this.nzSubmenuService.mode === 'horizontal' && this.platform.isBrowser) {
this.triggerWidth = this.cdkOverlayOrigin.nativeElement.getBoundingClientRect().width;
}
}
Expand Down Expand Up @@ -128,6 +129,7 @@ export class NzSubMenuComponent implements OnInit, OnDestroy, AfterContentInit,
private cdr: ChangeDetectorRef,
public nzSubmenuService: NzSubmenuService,
private nzUpdateHostClassService: NzUpdateHostClassService,
private platform: Platform,
@Host() @Optional() public noAnimation?: NzNoAnimationDirective
) {}

Expand Down
24 changes: 0 additions & 24 deletions components/modal/modal-util.ts

This file was deleted.

Loading

0 comments on commit 1cb86f2

Please sign in to comment.