Reputation: 1372
I've set up a simple app, consisting of two components: the main app and a banner. Banner is rendered within the app component and the idea is to toggle the visibility of the banner from the dashboard component.
The above works well the first time (i.e the banner is shown, then hidden) but on subsequent attempts, the banner remains hidden. Below is the code:
app.compoenent.html
<app-banner [showAlert]="showAlert" [alertMessage]="alertMessage"></app-banner>
<button (click)="onClick()">Apply</button>
app.compoenent.ts
import { Component, VERSION } from '@angular/core';
import { BannerComponent } from './components/banner/banner.component';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular ' + VERSION.major;
showAlert: boolean = false;
alertMessage: string = '';
onClick() {
this.alertMessage = 'Banner Message';
this.showAlert = true;
}
}
banner.compoenent.html
<div [hidden]="!showAlert">
<div>
<span>
{{alertMessage}}
</span>
<a class="close" (click)="closeAlert()" style="text-decoration: underline">[close]</a>
</div>
</div>
banner.compoenent.ts
import {Component, HostBinding, Input, OnInit} from '@angular/core';
@Component({
selector: 'app-banner',
templateUrl: './banner.component.html',
styleUrls: ['./banner.component.scss']
})
export class BannerComponent implements OnInit {
@Input() alertMessage!: string;
@Input() showAlert: boolean = false;
@Input() open() {
this.showAlert = true;
}
constructor() { }
ngOnInit(): void {
}
closeAlert(): void {
this.showAlert = false;
}
}
In the above example, when the button is clicked, the following code is executed in app.component.ts:
this.alertMessage = 'error';
this.showAlert = true;
This correctly shows the banner div. The banner component contains a link tag for which the event handler sets the showAlert property to false to hide the banner div - again this also works as expected.
However, now if the button in the app component is clicked again for a second time, even though the showAlert property is being set to true again, the banner remains hidden.
A Stackblitz has ben setup to demonstrate:
https://stackblitz.com/edit/angular-ivy-9sadyj
Can't see where i'm going wrong, any insight would be welcomed.
Upvotes: 1
Views: 585
Reputation: 5261
The issue:
At the moment your are just hiding the alert. So it never gets recreated, but rather stays in the DOM. This way it never gets passed new values from the dashboard component, as far as the dashboard is concerned it did its job.
A solution:
Just render your banner conditionally on a boolean in your dashboard component, to take it out of the DOM entirely and add it again:
In dashboard.component.ts:
showBanner = true
In the dashboard template:
<app-banner *ngIf="showBanner" [alertMessage]="alertMessage"></app-banner>
And then just flip that boolean with any logic:
For instance an @Output emitting an event.
Here's a working example for you on StackBlitz.
Some notes:
The way you are trying to hide the element only works when you move the 'showAlert'-logic to the child component, and only part of the component will be hidden (not the button).
But even then I would use "display:none;" over "visibility:hidden;" so there would be no dead space on the page.
Upvotes: 1