Applying different background images with the same component based in Angular?

549 views Asked by At

I have a nav-menu component and this component is the same for all the pages except I want the image property to change. What I mean is that I want different background images for different pages. For example I want the red car to be for the contact page, the grey car for the about page. How can I achieve that? Here is my code:

    <div>
      <nav class="navbar navbar-expand-md navbar-dark bg-dark">
        <a class="navbar-brand" href="#"></a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
          aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="container">
          <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav text-uppercase">
              <li class="nav-item">
                <a class="nav-link" href="#">Home</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">Services</a>
              </li>
              <li class="nav-item">
                <a routerLink="/about" class="nav-link">About</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">Reviews</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">Locations</a>
              </li>
              <li class="nav-item">
                <a routerLink="/contact" class="nav-link">Contacts</a>
              </li>
            </ul>
          </div>
        </div>
      </nav>
      <img [src]="blackcar" alt="blackcar" class="black-car">
    </div>

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-nav-menu',
  templateUrl: './nav-menu.component.html',
  styleUrls: ['./nav-menu.component.scss']
})
export class NavMenuComponent implements OnInit {

  blackcar = "assets/images/blackcar.png";
  redcar = "assets/images/redcar.png";
  greycar = "assets/images/greycar.png";

  constructor() { }

  ngOnInit(): void {
  }

}

2

There are 2 answers

0
Bargros On

The cleanest way to do this would be to use css to load the images as backgrounds. Then the background displayed is based on some condition that will result on one of the enumerations of background-type.ts or BackgroundType, so your solution should look like something between these lines:

nav-menu.component.scss:

.black-car {
   background-image: url("assets/images/blackcar.png");
   background-size:100% 100%;
}
.red-car {
   background-image: url("assets/images/redcar.png");
   background-size:100% 100%;
}
.grey-car {
   background-image: url("assets/images/greycar.png");
   background-size:100% 100%;
}

background-type.ts

// we create an enum so we can potentally just pass the enumeration value onto the nav  menu input property
export enum BackgroundType {
   BlackCar = 'black-car'
   RedCar = 'red-car',
   GreyCar = 'grey-car'
}

nav-menu.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { BackgroundType } '../model/background-type.ts'; // i would add this enum to your models directory or create one for enums

@Component({
  selector: 'app-nav-menu',
  templateUrl: './nav-menu.component.html',
  styleUrls: ['./nav-menu.component.scss']
})
export class NavMenuComponent {

  @Input()
  public backgroundType: BackgroundType; // this will allow us to set the background based on some condition that will tell us what type of background to display


  constructor() { }

}

nav-menu.component.html

<div>
      < --! notice the ngClass -->
      <nav class="navbar navbar-expand-md navbar-dark bg-dark" [ngClass]="backgroundtype">
        <a class="navbar-brand" href="#"></a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
          aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="container">
          <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav text-uppercase">
              <li class="nav-item">
                <a class="nav-link" href="#">Home</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">Services</a>
              </li>
              <li class="nav-item">
                <a routerLink="/about" class="nav-link">About</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">Reviews</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="#">Locations</a>
              </li>
              <li class="nav-item">
                <a routerLink="/contact" class="nav-link">Contacts</a>
              </li>
            </ul>
          </div>
        </div>
      </nav>
      <img [src]="blackcar" alt="blackcar" class="black-car">
    </div>
3
misha1109 On

I would listen to the Angular Router events using a subscription and based on the url choose the current color. Then in the View bind the color variable to src, alt, and class attributes.

in your nav-menu.component.ts listen to the route changes using Angular Router:


export class NavMenuComponent implements OnInit {
  currentColor: string;
  routeColors = {
    '/contact': 'black',
    '/about': 'grey'
  }

  constructor(private router: Router) { 
    router.events.subscribe(event:Event => {
      if(event instanceof NavigationEnd) {
        currentColor = routeColors[event.url];
      }
    });
  }

  ngOnInit(): void {
  }

}

Then in nav-menu.html bind the properties to currentColor variable:

...
          </div>
        </div>
      </nav>
      <img [src]="'assets/images/' + currentColor + 'car.png'" [alt]="currentColor + 'car'" [ngClass]="currentColor + '-car'">
    </div>