Home > Mobile >  Angular hide element from child component
Angular hide element from child component

Time:10-30

since I can't find any straight option maybe someone will help me here. The problem is that I have Angular project with following structure:

<app-navigation></app-navigation>

<router-outlet></router-outlet>

<app-footer></app-footer>

and there is a case, where only one component shouldn't have navigation bar visible. Is it possible to hide <app-navigation> from within <router-outlet> component?

CodePudding user response:

You could create a shared service that is injected into both the app component and any other pages that need to hide the navigation component.

Example of a shared service that exposes an observable toggle:

display.service.ts

@Injectable({
  providedIn: 'root'
})
export class DisplayService {
  
  public constructor() {
    this.showNavigation$ = this.showNavigation.asObservable();
  }
  public showNavigation$: Observable<boolean>;

  private showNavigation: Subject<boolean> = new Subject<boolean>();  

  public setNavigationVisibility(visible: boolean): void {
    this.showNavigation.next(visible);
  }
}

This services exposes an observable that can be subscribed to, and a method for emitting values via the observable.

The components that you want to hide the navigation bar in would hide the navigation bar in ngOnInit and show it again in ngOnDestroy.

component.ts

@Component({
  selector: 'app-hide-navigation',
  template: `<p>COMPONENT</p>`,
})
export class HideNavigationComponent implements OnInit, OnDestroy {

  constructor(private displayService: DisplayService) {
  }

  ngOnInit(): void {
    this.displayService.setNavigationVisibility(false);
  }

  ngOnDestroy(): void {
    this.displayService.setNavigationVisibility(true);
  }
}

Your app component could then subscribe to the observable and set the visibility accordingly:

app.component.ts

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  constructor(private displayService: DisplayService) {}

  showNavigation = true;

  private destroyed: Subject<void> = new Subject<void>();

  ngOnInit(): void {
    this.displayService.showNavigation$
      .pipe(takeUntil(this.destroyed))
      .subscribe((visible: boolean) => {
        this.showNavigation = visible;
      });
  }

  ngOnDestroy(): void {
    this.destroyed.next();
  }
}

app.component.html

<app-navigation *ngIf="showNavigation"></app-navigation>
<router-outlet></router-outlet>

The benefit of using an observable like this is that you can easily combine this with an OnPush change detection strategy rather than directly binding to a public boolean property on the service.

Stackblitz demo: https://stackblitz.com/edit/angular-ivy-dk5gi8?file=src/app/app.component.html

CodePudding user response:

You can try something like this:

Add a condition to the app-navigation tag, on when should it be displayed. The value can be from any service.

<app-navigation *ngIf="appNavigationService.show"></app-navigation>

And, in the component from which you don't want to show the navigation bar, within the <router-outlet> you can set the value of that field in service class as false. And once you go out of the component, probably in ngOnDestroy you can set it back to true. And also, have the value as true by default.

  • Related