angulartypescriptserviceng-classsimplify

How do I shift my [ngClass] conditions into a separate ts file as a reusable code across all components, instead of repeating it in every html file?


Currently I have my codes working. However, my [ngClass] conditions are very bulky. Having it repeated in many components in the html makes it difficult to maintain if any change is needed and makes my code very messy.

Example in my html:

 <a type="button" href="#">
        <div [ngClass]="{
           'blue-filter': runTheme==='Blue',
           'green-filter': runTheme==='Green',
           'red-filter': runTheme==='Red',
           'hydrangea-filter': runTheme==='Hydrangea',
           'sakura-filter': runTheme==='Sakura',
           'lavender-filter': runTheme==='Lavender',
           'mediterranean-filter': runTheme==='Mediterranean',
           'industrial-filter': runTheme==='Industrial',
           'minimalist-filter': runTheme==='Minimalist',
           'bohemian-filter': runTheme==='Bohemian',
           'forest-filter': runTheme==='Forest',
           'beach-filter': runTheme==='Beach',
           'sea-filter': runTheme==='Sea',
           'spring-filter': runTheme==='Spring',
           'winter-filter': runTheme==='Winter',
           'summer-filter': runTheme==='Summer',
           'autumn-filter': runTheme==='Autumn'
          }">
          <img src="./assets/iconsTopbar2px/building07.svg" />
        </div>
      </a>

      <a type="button">
        <div [ngClass]="{
           'blue-filter': runTheme==='Blue',
           'green-filter': runTheme==='Green',
           'red-filter': runTheme==='Red',
           'hydrangea-filter': runTheme==='Hydrangea',
           'sakura-filter': runTheme==='Sakura',
           'lavender-filter': runTheme==='Lavender',
           'mediterranean-filter': runTheme==='Mediterranean',
           'industrial-filter': runTheme==='Industrial',
           'minimalist-filter': runTheme==='Minimalist',
           'bohemian-filter': runTheme==='Bohemian',
           'forest-filter': runTheme==='Forest',
           'beach-filter': runTheme==='Beach',
           'sea-filter': runTheme==='Sea',
           'spring-filter': runTheme==='Spring',
           'winter-filter': runTheme==='Winter',
           'summer-filter': runTheme==='Summer',
           'autumn-filter': runTheme==='Autumn'
          }">
          <img src="./assets/iconsTopbar2px/ESS.svg" />
        </div>
      </a>

      <a type="button" routerLink="/login">
        <div [ngClass]="{
           'blue-filter': runTheme==='Blue',
           'green-filter': runTheme==='Green',
           'red-filter': runTheme==='Red',
           'hydrangea-filter': runTheme==='Hydrangea',
           'sakura-filter': runTheme==='Sakura',
           'lavender-filter': runTheme==='Lavender',
           'mediterranean-filter': runTheme==='Mediterranean',
           'industrial-filter': runTheme==='Industrial',
           'minimalist-filter': runTheme==='Minimalist',
           'bohemian-filter': runTheme==='Bohemian',
           'forest-filter': runTheme==='Forest',
           'beach-filter': runTheme==='Beach',
           'sea-filter': runTheme==='Sea',
           'spring-filter': runTheme==='Spring',
           'winter-filter': runTheme==='Winter',
           'summer-filter': runTheme==='Summer',
           'autumn-filter': runTheme==='Autumn'
          }">
          <img src="./assets/iconsTopbar2px/arrowCircleBrokenRight01.svg" />
        </div>
      </a>

How to create a single typescript file or a service file to place the conditions inside?

Do note that my runTheme is retrieving its data from a service - ColorSchemeService.

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { ColorSchemesService } from '../color-schemes.service';

@Component({
  selector: 'app-top-panel',
  templateUrl: './top-panel.component.html',
  styleUrls: ['./top-panel.component.css']
})


export class TopPanelComponent {
  runTheme: any;

  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private colorSchemes: ColorSchemesService,
  ) {
    this.colorSchemes.data$.subscribe(data => {
      this.runTheme = data;
    })
  }

I am still not sure of how to format my codes properly. Have tried creating a new colorFilter.ts file and link to my component's ts and html, but met with errors.

import { ColorSchemesService } from "./color-schemes.service";

export const colorFilter = [
  runTheme: any;

constructor(
  private colorSchemes: ColorSchemesService,
) {
  this.colorSchemes.data$.subscribe(data => {
    this.runTheme = data;
  })
}

  blue-filter04: runTheme === 'Blue',
  green-filter04: runTheme === 'Green',
  red-filter04: runTheme === 'Red',
  hydrangea-filter04: runTheme === 'Hydrangea',
  sakura-filter04: runTheme === 'Sakura',
  lavender-filter04: runTheme === 'Lavender',
  mediterranean-filter04: runTheme === 'Mediterranean',
  industrial-filter04: runTheme === 'Industrial',
  minimalist-filter04: runTheme === 'Minimalist',
  bohemian-filter04: runTheme === 'Bohemian',
  forest-filter04: runTheme === 'Forest',
  beach-filter04: runTheme === 'Beach',
  sea-filter04: runTheme === 'Sea',
  spring-filter04: runTheme === 'Spring',
  winter-filter04: runTheme === 'Winter',
  summer-filter04: runTheme === 'Summer',
  autumn-filter04: runTheme === 'Autumn'
]

Any guidance would be greatly appreciated!


Solution

  • you can use a directive like this:

    import { Directive, HostBinding, OnInit } from '@angular/core';
    
    @Directive({
      selector: '[appMyDirective]',
    })
    export class MyDirectiveDirective implements OnInit {
      filterclass = '';
      runTheme = 'Green';
      @HostBinding('class') filterClass = 'blue-filter04';
      constructor() {}
    
      ngOnInit(): void {
        switch (this.runTheme) {
          case 'Blue':
            this.filterClass = 'blue-filter04';
            break;
          case 'Green':
            this.filterClass = 'green-filter04';
            break;
          case 'Red':
            this.filterClass = 'red-filter04';
            break;
        }
      }
    }
    

    this is an example here