broadband
broadband

Reputation: 3488

How to change html layout based on Route in Angular 8?

This is my app.module.ts file (the imporant snippet only):

imports: [
  BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
  ...
  RouterModule.forRoot([

    // basic
    { path: 'basic', component: StartComponent, data: { useBasicLayout: 'yes' } },
    { path: 'basic/workspace/:id', component: WorkspaceComponent },

    // full blown layout
    { path: '', component: StartComponent },
    { path: 'workspace/:id', component: WorkspaceComponent },
  ]).

What I want to accomplish is that if URL is like this: 'http://example.com/basic' the HTML shown is basic layout (I have defined components like ribbon and ribbon-basic).

If I navigate just 'http://example.com/' the full blown HTML layout is shown.

I tried with next code in app.component.ts because it's the first component that starts.

import { Component } from '@angular/core';
import { WorkspaceService } from './components/workspace/workspace.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {

  basicLayoutEnabled: boolean = false;

  constructor(
    private _wService: WorkspaceService,
    private _activatedRoute: ActivatedRoute,
    private _router: Router) {

    this._activatedRoute.data.subscribe(data => {
      console.log("Data parameters: " + data);
      // the data is empty here
      if (data.useBasicLayout == true) {
        this._wService.basicLayoutEnabled = true;
      }
    });
  }

  ngOnInit() {}    
  ngOnDestroy() {}
}

And here is the view app.component.html:

<div fxFlexFill fxLayout="column">
  <div fxFlex="none">
    <app-ribbon *ngIf="!basicLayoutEnabled"></app-ribbon>
    <app-ribbon-basic *ngIf="basicLayoutEnabled"></app-ribbon-basic>
  </div>
  <div fxLayout="row" style="overflow: hidden; flex: auto;">
    <router-outlet></router-outlet>
  </div>
  <div fxFlex="none">
    <app-status-bar fx></app-status-bar>
  </div>
</div>

Upvotes: 0

Views: 1892

Answers (2)

StepUp
StepUp

Reputation: 38114

Try to avoid rendering the whole page until you've not known what to show. So it is possbilr to add the following condition *ngIf="showInterface" to decide whether ng-container should be shown:

<ng-container *ngIf="showInterface">
    <div fxFlexFill fxLayout="column">
      <div fxFlex="none">
        <app-ribbon *ngIf="!basicLayoutEnabled"></app-ribbon>
        <app-ribbon-basic *ngIf="basicLayoutEnabled"></app-ribbon-basic>
      </div>
      <div fxLayout="row" style="overflow: hidden; flex: auto;">
        <router-outlet></router-outlet>
      </div>
      <div fxFlex="none">
        <app-status-bar fx></app-status-bar>
      </div>
    </div>
</ng-container>

TypeScript:

export class AppComponent {

  basicLayoutEnabled: boolean = false;
  showInterface = false; // TSLint likes such declaration:)

  constructor(
    private _wService: WorkspaceService,
    private _activatedRoute: ActivatedRoute,
    private _router: Router) {

    this._activatedRoute.data.subscribe(data => {
      console.log("Data parameters: " + data);
      // the data is empty here
      if (data.useBasicLayout == true) {
        this._wService.basicLayoutEnabled = true;
      }
      if ( data.useBasicLayout == false || data.useBasicLayout == true) {
          this.showInterface = true;
      }
    });
  }

  ngOnInit() {}    
  ngOnDestroy() {}
}

In addition, I've thought to use the following condition:

if ( data.useBasicLayout)

However, it looks like data.useBasicLayout can have false value.

UPDATE:

If you want to take route parameters, then use the following construction:

 constructor(public route: ActivatedRoute) {}

 this.route.queryParams.takeUntil(this.ngUnsubscribe).subscribe(x => {
    console.log(`route params: `, x)
})

Upvotes: 0

Adrien PESSU
Adrien PESSU

Reputation: 557

You can use the router to detect the change :

constructor(router: Router) {
   this.router.events
     .pipe(filter(event => event instanceof NavigationEnd))
     .subscribe(({ urlAfterRedirects }: NavigationEnd) => {
       const url = urlAfterRedirects.split(';')[0];
       if(url === '/basic') {
         this.displayASpecificHtmlPart = true;
       }
     });
}

Upvotes: 2

Related Questions