簡體   English   中英

ExpressionChangedAfterItHasBeenCheckedError /角4角7

[英]ExpressionChangedAfterItHasBeenCheckedError / Angular 4-Angular 7

我將代碼從Angular 4更新到了Angular 7,突然出現了這個錯誤。 互聯網上有太多關於此的文章,但似乎沒有奏效。 有人可以指出我為什么出現此錯誤嗎? 錯誤來自面包屑

我的錯誤

ExpressionChangedAfterItHasBeenCheckedError:表達式在檢查后已更改。 先前的值:“ showBreadcrumbsSiteMetaData:false”。 當前值:“ showBreadcrumbsSiteMetaData:true”。

at viewDebugError (core.js:20342)
at expressionChangedAfterItHasBeenCheckedError (core.js:20330)
at checkBindingNoChanges (core.js:20432)
at checkNoChangesNodeInline (core.js:23307)
at checkNoChangesNode (core.js:23292)
at debugCheckNoChangesNode (core.js:23896)
at debugCheckDirectivesFn (core.js:23824)
at Object.eval [as updateDirectives] (HomeComponent.html:6)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:23813)
at checkNoChangesView (core.js:23191)

Home.Component.html

<div class="wrapper" >
  <navbar [metaData]="navBarMetadata" [userInfo]="navbarUserInfo" [helpButtonRoute]="navbarHelpButtonRoute"
        [menuItems]="sidebarRoutes" [settingsMenuItems]="settingsMenuItems"
        [languagesMenuItems]="languagesMenuItems"
        [rs_logo]="rs_logo"></navbar>
    <details-bar [breadscrumbsMetaData]="breadscrumbsMetaData" [breadcrumbsSiteMetaData]="breadcrumbsSiteMetaData"
             [showBreadcrumbsSiteMetaData]="showBreadcrumbsSiteMetaData"></details-bar>

  <div class="main-panel" #mainPanel (scroll)="onScroll($event)">
    <div class="container ">
      <div class="current-component">
        <simple-notifications [options]="notificationOptions"></simple-notifications>
        <router-outlet></router-outlet>
      </div>
    </div>
  </div>
</div>

Home.Component.ts

 export class HomeComponent implements OnInit, AfterViewInit {

    notificationOptions: any = AppConstants.NOTIFICATION_OPTIONS;
    sidebarRoutes: NavbarRouteInfo[];
    settingsMenuItems: NavbarRouteInfo[];
    navBarMetadata: NavBarMetadata[];
    navbarUserInfo: NavBarUserInfo;
    navbarHelpButtonRoute: string;
    rs_logo: string;
    languagesMenuItems: LanguageInfo[];
    breadscrumbsMetaData: BreadscrumbMetadata[];
    breadcrumbsSiteMetaData: BreadscrumbMetadata[];
    showBreadcrumbsSiteMetaData: boolean;
    entityTypeList: RSEntityType[];
    @ViewChild('mainPanel') mainPanelDiv: ElementRef;
    activeAppKey: string;
    protected alive = true;
    private notificationTitles: { error: string };

    constructor(public notificationsManager: NotificationsManager,
          private authGuard: AppAuthGuard,
          private homeEventBus: HomeEventBus,
          private userManagementService: UserManagementService,
          private homeService: HomeService,
          private authService: AuthService,
          private activatedRoute: ActivatedRoute,
          private translate: TranslateService,
          private dataService: DataService) {
          this.breadcrumbsSiteMetaData = [];
          this.showBreadcrumbsSiteMetaData = false;
          this.activeAppKey = '';
          this.entityTypeList = [];
          this.initMessages();}

          initMessages() {
             this.translate.stream('home.msg').subscribe((res) => {
             this.notificationTitles = {
             'error': res['error']
             }
          }
     );

}

ngOnInit() {

    this.notificationsManager.showSpinner();
    this.translate.setDefaultLang
    (sessionStorage.getItem(AppConstants.LANGUAGE));
    this.subscribeEvents();
    this.initNavBar();
    this.initSideBar();
    this.initLanguageBar();
    this.notificationsManager.hideSpinner();
}

ngAfterViewInit() {
    this.initNavBar();
    if (((this.activeAppKey) === undefined || (this.activeAppKey) === null) || 
    this.activeAppKey.trim().length === 0) {
    this.activeAppKey = sessionStorage.getItem(AppConstants.APP_KEY);
    }

    if (this.authGuard.isAccessTokenDefined()) {
    this.dataService.loadUserIdEmailList(this.activeAppKey);
    }
}

initNavBar() {
    this.rs_logo = environment.API_BASE_URL + '/' + 'resources/internal-assets/images?name=rs-logo.png';
    this.setNavBarMetaData();
    this.navbarHelpButtonRoute = AppConstants.HELP_ROUTE;
    this.navbarUserInfo = new NavBarUserInfo('assets/img/default-avatar.png', '');
    this.loadUserImg();
 }

 setNavBarMetaData() {
     this.translate.stream('navbar').subscribe((res) => {
         this.navBarMetadata = [{
             path: 'profile',
             params: {},
             title: res['profile'],
             index: -1
         }];
     });
 }


this.homeEventBus.breadcrumbsSiteMetaDataUpdateEvent$.subscribe(data => {
  if (data) {
    // this.fetchEntityTypes();
    this.showBreadcrumbsSiteMetaData = true;
  } else {
    // this.breadcrumbsSiteMetaData = [];
    this.showBreadcrumbsSiteMetaData = false;
  }
});

通常,這表示設計流程,但是,在某些情況下,異步模式會迫使您在進行角度檢查后進行更改。

為了重新啟動變更檢測周期,您必須

導入ChangeDetectorRef

import { ChangeDetectorRef } from '@angular/core';

將其注入您的組件中,

public constructor(private readonly changeDetectorRef: ChangeDetectorRef) {
}

當您確定已完成更改時,將組件標記為已更改,然后觸發更改

this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();

請注意,您知道控制檢測周期,因此,您必須確保自己不會循環請求繼續強制檢測,否則會破壞萬物的目的。

更新

  this.homeEventBus.breadcrumbsSiteMetaDataUpdateEvent$
      .pipe(
          delay(0),
          tap(data => {
              if (data)
                this.showBreadcrumbsSiteMetaData = true;
              else
                this.showBreadcrumbsSiteMetaData = false;
            })
      ).subscribe();

要么

setTimeout(() => {
    this.homeEventBus.breadcrumbsSiteMetaDataUpdateEvent$.subscribe(data => {
      if (data) {
        // this.fetchEntityTypes();
        this.showBreadcrumbsSiteMetaData = true;
      } else {
        // this.breadcrumbsSiteMetaData = [];
        this.showBreadcrumbsSiteMetaData = false;
      }
    });
  });

您的代碼在修改ngAfterViewInit的property的值時可能會出現問題,這可能是導致問題的原因

所以你應該把ngAfterViewInit的代碼作為bel

ngAfterViewInit() {
   setTimeout(() => {
    this.initNavBar();
    if (((this.activeAppKey) === undefined || (this.activeAppKey) === null) || 
    this.activeAppKey.trim().length === 0) {
    this.activeAppKey = sessionStorage.getItem(AppConstants.APP_KEY);
    }

    if (this.authGuard.isAccessTokenDefined()) {
    this.dataService.loadUserIdEmailList(this.activeAppKey);
    }
  }
}

有關詳細信息,請檢查: https : //blog.angular-university.io/angular-debugging/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM