I created my own directive for table header (thead tag). That makes that header of table is "sticky" (has fixed position and is visible during scroll table). It looks like that:
sticky.directive.ts
const NAVBAR_HEIGHT = 55;
@Directive({
selector: '[sticky]',
})
export class StickyDirective implements AfterViewInit {
@Input()
@HostBinding('style.width.px')
stickyWidth: string;
topPosition: number;
constructor(private _element: ElementRef, private _window: WindowRef) { }
ngAfterViewInit() {
let boundingClientRect = this._element.nativeElement.getBoundingClientRect();
this.topPosition = boundingClientRect.top - NAVBAR_HEIGHT;
}
@HostListener('window:scroll', ['$event'])
handleScrollEvent(e) {
if (this._window.nativeWindow.pageYOffset > (this.topPosition) ) {
this._element.nativeElement.classList.add('stick');
} else {
this._element.nativeElement.classList.remove('stick');
}
}
}
And is called in this way:
<div class="card-block" >
<table #table class="table table-bordered">
<thead sticky [stickyWidth]="table.offsetWidth">
It's work fine, but in console I got error:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '1632'. Current value: '1615'.
at viewDebugError (core.es5.js:8633)
at expressionChangedAfterItHasBeenCheckedError (core.es5.js:8611)
at checkBindingNoChanges (core.es5.js:8775)
at checkNoChangesNodeInline (core.es5.js:12329)
at checkNoChangesNode (core.es5.js:12303)
at debugCheckNoChangesNode (core.es5.js:12922)
at debugCheckDirectivesFn (core.es5.js:12824)
at Object.View_PageListComponent_0.co [as updateDirectives] (PageListComponent.html:23)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:12806)
at checkNoChangesView (core.es5.js:12123)
at callViewAction (core.es5.js:12487)
Anyone can explain me what I did wrong? How can I secure my app against this exception or what is the correct way creating similar directive? Thanks in advance
the moment you're updating table.offsetWidth
is happening after Angular has finished it's changeDetection
cycle .
It would be better to share the code, but without seeing it, here is what you possibly need to do :
Move that update in better and proper timing, and make sure the process of changing that is a one way flow.
Use detectorRef.detectChanges()
after your update
Put the update inside a setTimeout
Any of them would work, but best is the first one, the others are your last resort