Fabien Greard
Fabien Greard

Reputation: 1894

Angular 2, ngOnChanges, ngDoCheck

Hello folks i have come to you with many thoughs, i would like to talk about something i cannot get.

Simple service studies

So we have here one service who is triggered by a component.

This is a simple service who commit an observable element when it get triggered :

return this.subject.asObservable();

Then we have a component getting this :

this.alertService.getMessage().subscribe(message => { this.message = message; });

Ok until now everything is ok. This logic is include into a component , his selector name is <alert></alert>

Nested Component

Here we have another component with this <alert></alert>.

<div class="article-page-container">
  <alert></alert>
  <ul *ngIf="!alert" class="page-nav-container">
    <li *ngFor="let page of pageArray" (click)="pageHandlerEvent(page)" [ngClass]="{ 'page-active': page == pageActive}">{{ page }}</li>
  </ul>
</div>

Did you get it ? What i am trying to do is when the nested component is getting an alert it should turn of the page nav class.

I have found one solution, this is not a problem about how to makes it works, but find the right one, made something that people will be proud of ?

ngDoCheck

Do i need to say more ? It's ugly , i get like 1000000000 useless check, but it will works.

ngDoChanges

Should only happens when something inside my component is actually getting 'change', right ?

So i have try this :

<div class="article-page-container">
  <alert (alertOn)="toggleNav($event)"></alert>
  <ul *ngIf="!alert" class="page-nav-container">
    <li *ngFor="let page of pageArray" (click)="pageHandlerEvent(page)" [ngClass]="{ 'page-active': page == pageActive}">{{ page }}</li>
  </ul>
</div>

Everytime an alert is triggered i do a simple this.alertOn.emit(true),

However ngOnChanges doesn't work at all. And this will result with :

core.umd.js:3493 ORIGINAL EXCEPTION: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.

Other tests

I know you guys are great, so if you have any idea about what should be done in a 'correct way'.

Have an awesome day !

Upvotes: 2

Views: 3217

Answers (2)

Fabien Greard
Fabien Greard

Reputation: 1894

So here the result i found that looks great !

@ViewChild(AlertComponent) AlertComponent: AlertComponent; 

.... 

ngAfterContentChecked () {
  this.alert = (this.AlertComponent.message) ? true : false;
}

Simple, it doesn't need to change the logic also it will not loose any perf compare to ngDocheck() with it's 10000k tests ...

Upvotes: 0

Jonathan Niu
Jonathan Niu

Reputation: 321

Have you tried moving the

this.alertService.getMessage().subscribe(message => { this.message = message; });

subscription to your parent container, and then sending the message as an input through

<alert [message]=message></alert>

this way you can also include some logic to change an display flag boolean for your page-nav-container in the subscribe function

Upvotes: 2

Related Questions