繁体   English   中英

Angular 8 在页面加载后添加 class 错误:ExpressionChangedAfterItHasBeenCheckedError

[英]Angular 8 add class after page load Error: ExpressionChangedAfterItHasBeenCheckedError

正如标题所示,我正在尝试在页面加载后将 class 添加到div元素! 我有一个条件isTrue ,并且在页面加载后执行的 angular function ngAfterViewInit()使isTrue值为true ,然后添加hideOnLoad 当然我可以使用标准javascriptjquery ,但我必须使用 angular 方式。 本质上,最终结果应该是, div.index-logo-wrapper在页面加载后慢慢淡出。 我的想法是在加载后添加一个 class 以逐渐降低opacity ,非常感谢您的输入。

 import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-index-section', templateUrl: './index-section.component.html', styleUrls: ['./index-section.component.scss'] }) export class IndexSectionComponent implements OnInit { isTrue: boolean = false; public innerWidth: any; constructor() { } ngOnInit() { } ngAfterViewInit() { this.innerWidth = window.innerWidth; if (this.innerWidth < 1000) { this.isTrue = true; alert(this.isTrue); } } }
 <section class="index-section"> <div class="index-logo-wrapper" [class.hideOnLoad]="isTrue"> <figure> <img src="assets/icons/logo_mobile.svg" alt=" logo"> </figure> </div> <div class="index-media-wrapper"> <div class="media-container"> <iframe src="https://player.vimeo.com/video/128014070?autoplay=1&color=ffffff&title=0&byline=0&portrait=0" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Itaque contra est, ac dicitis; Duo Reges: constructio interrete. Videsne quam sit magna dissensio? </p> </div> </div> </section>

这是我控制台中的错误:

在此处输入图像描述

您不应该更改与 Angular 挂钩内的绑定相关的内容,因为这会干扰更改检测过程。 将变更检测视为绞肉机。 你应该只尝试在肉进出之前或之后换肉——你不能在过程中间改变它。

您可以做的是将其转换为 RxJs Stream 并将其与模板中的async pipe 一起使用。 通过这种方式,Angular 将知道在更改检测期间发生了某些变化,并在完成后再次触发它。

或者您可以注入ChangeDetectorRef并在您更改与生命周期挂钩中的绑定相关的内容的地方执行this.changeDetectorRef.markForCheck() 对于您的情况,它实际上与async pipe 相同。

这是更一般的建议,这是针对您的特定情况的解决方案,它也适用于 Angular Universal(服务器端渲染):

import { DOCUMENT } from '@angular/common';
import { Component, Inject, OnInit } from '@angular/core';

@Component({
  selector: 'app-index-section',
  templateUrl: './index-section.component.html',
  styleUrls: ['./index-section.component.scss']
})
export class IndexSectionComponent {
  readonly isTrue: boolean;

  constructor(@Inject(DOCUMENT) {defaultView}: Document) {
    this.isTrue = !defaultView || defaultView.innerWidth < 1000;
  }
}

Of course there will be no window size on the server, but accessing properties on window can cause errors in that environment and it is preferable not to use DOM API in your Angular app directly and use abstractions through tokens anyway.

您可以使用三元运算符动态添加 class ? . 如果isTrue则添加hideOnLoad ,否则 class 为空:

<div class="index-logo-wrapper" [ngClass]="isTrue ? 'hideOnLoad' : ''">

您可以通过以下方式动态添加 class

 <div class="index-logo-wrapper" [ngClass]="{'hideOnLoad':isTrue}">

或者

 <div class="index-logo-wrapper {{isTrue? 'hideOnLoad': ''}}">

正如另一个人所说,您可以使用以下解决方案:

<div class="index-logo-wrapper" [ngClass]="isTrue ? 'hideOnLoad' : ''">

但是当它用于单个 class 时,我更喜欢这种其他语法:

<div class="index-logo-wrapper" [class.hideOnLoad]="isTrue">

它更容易阅读和清洁。

暂无
暂无

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

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