2017-07-30 30 views
1

我對Angular 4不是很有經驗,所以我不確定這個問題是如何工作的。我得到以下錯誤;共享服務:ExpressionChangedAfterItHasBeenCheckedError:檢查後表達式已更改

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.

這是我的設置。我有一個使用<router-outlet></router-outlet>加載其他組件的組件「menus.component.ts」(MenusComponent)。錯誤發生在LocalService.placementListShow.value下面的代碼中。

<div class="row"> 
    ... 
</div> 
<!-- end row --> 
<div class="row"> 
    <div class="col-md-4 col-sm-4 col-xs-12 col-xl-3" *ngIf="LocalService.placementListShow.value"> 
    <div class="card m-b-20" *ngIf="LocalService.AllPlacements.Loaded && !LocalService.AllPlacements.Loading"> 
     ... 
     <button type="button" class="list-group-item" [ngClass]="{'active': LocalService.AllPlacements.Active.value==placement.id }" (click)="LocalService.AllPlacements.Activate(placement.id)" *ngFor="let placement of LocalService.AllPlacements.Placements">{{placement.title}}</button> 
     ... 
    </div> 
    <single-element-loader *ngIf="LocalService.AllPlacements.Loading"></single-element-loader> 
    </div><!-- end col--> 
    <div class="col-md-4 col-sm-4 col-xs-12 col-xl-3" *ngIf="LocalService.menuListShow.value"> 
    ... 
     <a [routerLink]="[menu.id]" class="list-group-item" [ngClass]="{'active': LocalService.PlacementMenus.Active.value==menu.id }" (click)="LocalService.PlacementMenus.Activate(menu.id)" *ngFor="let menu of LocalService.PlacementMenus.Menus">{{menu.title}}</a> 
    ... 
    <single-element-loader *ngIf="LocalService.PlacementMenus.Loading"></single-element-loader> 
    </div><!-- end col--> 
    <div class="col-md-8 col-sm-8 col-xs-12 col-xl-9"> 
    <router-outlet></router-outlet> 
    </div><!-- end col--> 
</div> 

想法是該組件將使用Angular路由器加載子組件。我想控制子組件中某些小部件的可見性,所以我設置了一個本地服務。

@Injectable() 
export class LocalService { 
    menuListShow = new BehaviorSubject(false); 
    placementListShow = new BehaviorSubject(true); 
    Menu: Menu = new Menu(); 
    AllPlacements: AllPlacements = new AllPlacements(); 
    PlacementMenus: PlacementMenus = new PlacementMenus(); 

    constructor(
     private MenuService: MenuService, 
     private route: ActivatedRoute, 
) { 
    } 

    changeMenuComponents(componentName: string): void { 
    alert ("Changing to: "+ componentName) 
    let menuState = { 
     'placementList': (that): void => { 
     that.menuListShow.next(false); 
     that.placementListShow.next(true); 
     }, 
     'menuList': (that): void => { 
     that.placementListShow.next(false); 
     that.menuListShow.next(true); 
     } 
    }; 
    menuState[componentName](this); 
    } 
} 

例如,我有一個MenuComponent和EditLinkComponent將被加載到MenusComponent中。根據主要組件中加載的組件,我想顯示2個小部件。但使用服務,我得到上述錯誤。

以下內容並不重要,但讓您更瞭解我正在嘗試做什麼。

我想顯示一個菜單位置列表,當用戶看到MenusComponent的索引時,當我點擊菜單位置時,它應該在該位置顯示菜單,當我點擊菜單時,它應該顯示鏈接菜單。當我點擊編輯鏈接時,它應該顯示EditLinkComponent。例如,這通過Angular路由器發生; #cms/menus然後#cms/menus/{menuid}然後#cms/menus/{menuid}/links/{linkid} /編輯

問題是如果我刷新; #cms/menus/{menuid}/links/{linkid} /編輯我得到錯誤;

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.

我認爲這與嘗試從服務器加載放置對象和菜單對象有關。

+0

文章[所有你需要知道的關於'ExpressionChangedAfterItHasBeenCheckedError'錯誤](https://hackernoon.com/一切 - 你需要知道關於這個表達式changedafterithasbeencheckederror-error-e3fd9ce7dbb4)應該給你所有的答案 –

回答

0

以下是如何修復它(您需要手動觸發變化檢測):

@Injectable() 
export class LocalService { 
    menuListShow = new BehaviorSubject(false); 
    placementListShow = new BehaviorSubject(true); 
    Menu: Menu = new Menu(); 
    AllPlacements: AllPlacements = new AllPlacements(); 
    PlacementMenus: PlacementMenus = new PlacementMenus(); 

    constructor(
     private changeDetectorRef: ChangeDetectorRef, 
     private MenuService: MenuService, 
     private route: ActivatedRoute, 
) { 
    } 

    changeMenuComponents(componentName: string): void { 
    alert ("Changing to: "+ componentName) 
    let menuState = { 
     'placementList': (that): void => { 
     that.menuListShow.next(false); 
     that.placementListShow.next(true); 
     }, 
     'menuList': (that): void => { 
     that.placementListShow.next(false); 
     that.menuListShow.next(true); 
     } 
    }; 
    menuState[componentName](this); 
    this.changeDetectorRef.detectChanges(); 
    } 
} 
相關問題