简体   繁体   English

在使用 getElementById 的元素上使用 ngClass,元素为 null

[英]Using ngClass on an element that uses getElementById, element is null

I've got an html element with overflow: auto , but I want to give it a border only when it's scrollable.我有一个带有overflow: auto的 html 元素,但我只想在它可滚动时给它一个边框。

How do I evaluate the element's size from within ngClass without getting any kind of null errors?如何从 ngClass 中评估元素的大小而不会出现任何类型的空错误?

Note: The element's enclosing div doesn't get rendered until after getting a response from an observable.注意:元素的封闭 div 直到从 observable 获得响应后才会呈现。

Attempt 1:尝试 1:

The html element is set up like this: html 元素设置如下:

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

In my ngOnInit, I call a function to see if the given element can be scrolled.在我的 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;
    }
}

If I don't check for null, I get errors.如果我不检查空值,就会出错。 If I do check for null, then even if I have scrollable content, when the page is loaded, the border doesn't show up.如果我确实检查了 null,那么即使我有可滚动的内容,当页面加载时,边框也不会显示。

I thought the issue might be with this.loading, so I added the scroll check within the observable response, but after loading was set to false.我认为问题可能出在 this.loading 上,所以我在可观察响应中添加了滚动检查,但加载后设置为 false。 Still no border.仍然没有边界。

Attempt 2:尝试 2:

<div #textDiv [ngClass]="{'border-class': isScrollable}"> ... </div>

@ViewChild('textDiv') element: ElementRef;

/* ... */

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

But the border still doesn't show up on scrollable content when the page is loaded.但是当页面加载时边框仍然没有显示在可滚动内容上。

Attempt 3:尝试 3:

The only thing that has worked, is this hot mess:唯一有效的方法就是这个乱七八糟的:

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

Is there a way I can get this to work without calling setTimeout?有没有一种方法可以让我在不调用 setTimeout 的情况下工作?

The problem is here:问题在这里:

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

The isScrollable is not updating the value after it changes. isScrollable在更改后不会更新该值。

You can fix this, using a get and returning the value when ngAfterViewInit was already executed:你可以解决这个问题,使用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;
    }
}

Then in your html:然后在你的 html 中:

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

With that, it should work.有了这个,它应该工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM