【问题标题】:ExpressionChangedAfterItHasBeenCheckedError when passing the width of an element to my own directive.将元素的宽度传递给我自己的指令时出现 ExpressionChangedAfterItHasBeenCheckedError。
【发布时间】:2017-06-05 11:15:05
【问题描述】:

我为表头创建了自己的指令(thead 标记)。这使得表格的标题是“粘性的”(具有固定位置并且在滚动表格期间可见)。看起来是这样的:

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');
        }
    }
} 

并被这样称呼

<div class="card-block" >
   <table #table class="table table-bordered">
      <thead sticky [stickyWidth]="table.offsetWidth">

一切正常,但在控制台中出现错误:

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)

谁能解释我做错了什么?如何保护我的应用免受此异常的影响,或者创建类似指令的正确方法是什么?提前致谢

【问题讨论】:

标签: angular angular-directive angular2-hostbinding


【解决方案1】:

你更新 table.offsetWidth 的那一刻发生在 Angular 完成它的 changeDetection 循环之后。

最好分享代码,但看不到它,这是你可能需要做的:

  • 以更好、更合适的时机移动更新,并确保更改流程是单向流程。

  • 更新后使用detectorRef.detectChanges()

  • 将更新放在 setTimeout 中

其中任何一个都可以,但最好是第一个,其他是你最后的手段

【讨论】:

    猜你喜欢
    • 2019-10-04
    • 1970-01-01
    • 2017-02-18
    • 2018-04-08
    • 2015-07-18
    • 1970-01-01
    • 2014-11-14
    • 2020-09-22
    • 1970-01-01
    相关资源
    最近更新 更多