【问题标题】:Using ngClass on an element that uses getElementById, element is null在使用 getElementById 的元素上使用 ngClass,元素为空
【发布时间】:2020-03-21 04:53:44
【问题描述】:

我有一个带有 overflow: auto 的 html 元素,但我只想在它可滚动时给它一个边框。

如何在 ngClass 中评估元素的大小而不会出现任何类型的 null 错误?

注意:元素的封闭 div 直到从 observable 获得响应后才会被渲染。

尝试 1:

html元素是这样设置的:

<div ngIf="!loading">
    <div id="{{someID}}" [ngClass]="{'border-class': isScrollable}"> ... </div>
</div>

在我的 ngOnInit 中,我调用了一个函数来查看给定的元素是否可以滚动。

ngOnInit() {

     // this.loading gets set to false after an observable is returned

    /* ... */

    // scroll check
    let e = document.getElementById(`${this.someID}`);

    if (element !== null) {
        this.isScrollable = e.scrollHeight > e.clientHeight;
    }
}

如果我不检查 null,我会得到错误。如果我检查null,那么即使我有可滚动的内容,当页面加载时,边框也不会出现。

我认为问题可能出在 this.loading 上,所以我在可观察响应中添加了滚动检查,但加载后设置为 false。仍然没有边界。

尝试 2:

&lt;div #textDiv [ngClass]="{'border-class': isScrollable}"&gt; ... &lt;/div&gt;

@ViewChild('textDiv') element: ElementRef;

/* ... */

ngAfterViewInit() {
    this.isScrollable = this.element.scrollHeight > this.element.clientHeight;
}

但是当页面加载时,边框仍然没有显示在可滚动内容上。

尝试 3:

唯一奏效的就是这团烂摊子:

setTimeout( () => {
    this.isScrollable = this.element.scrollHeight > this.element.clientHeight;
});

有没有一种方法可以在不调用 setTimeout 的情况下使其工作?

【问题讨论】:

    标签: javascript html angular


    【解决方案1】:

    问题出在这里:

    <div ngIf="!loading">
        <div id="{{someID}}" [ngClass]="{'border-class': isScrollable}"> ... 
    </div>
    

    isScrollable 在更改后不会更新值。

    您可以解决这个问题,使用 get 并在 ngAfterViewInit 已经执行时返回值:

    export class CustomComponent implements AfterViewInit {
        private afterViewInitExecuted = false;
        @ViewChild('textDiv') element: ElementRef;
    
        public get isScrollable() {
          if(this.afterViewInitExecuted) {
             return this.element.scrollHeight > this.element.clientHeight;
          }
          return false;
        }
        ngAfterViewInit() {
           this.afterViewInitExecuted = true;
        }
    }
    

    然后在你的 html 中:

    <div ngIf="!loading">
        <div id="{{someID}}" [ngClass]="{'border-class': isScrollable() }"> ... 
    </div>
    

    有了它,它应该可以工作了。

    【讨论】:

    • 即使我检查 afterViewInitExecuted,我仍然会收到一条错误消息,提示“无法读取未定义的属性 'nativeElement'”。相反,我检查 if (this.element) 并且有效!谢谢!
    猜你喜欢
    • 2014-12-24
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    相关资源
    最近更新 更多