简体   繁体   中英

How to create a global ngClass method in Angular?

Using Angular 7, I have created an ngClass method in my component.ts file and works great.

What I want is to use that same method in all my components without re-writing the code, but I'm not sure where that code is supposed to go. I tried putting it in app.component.ts, but that didn't work.

Where can I put an ngClass method so it is global to all my components?

Code is pretty simple. It just assigns a class to a money amount to color it green if its positive and red if it's negative.

moneyClass(amount) {
    if(amount>=0)
        return 'moneyGreen';
    else
        return 'moneyRed';
}

and in the html:

    <div [ngClass]="moneyClass(amount)">{{amount}}</div>

I see three possible solutions:

1) Create a class to extend

export class MyNgClass {
  ngClassHandler() {}
}

and then extend it in those components you need to reuse the method

export class MyComponent extends MyNgClass {}

2) Create an exported function and then save a reference to it in component

export function ngClassHandler() {}

export class MyComponent {
  handler = ngClassHandler;
}

3) Use a pipe

@Pipe({
  name: 'myPipe'
})
export class MyPipe implements PipeTransform {
  transform(data: any): any {
    // place your logic here
  }
}

Then use it in component's template

<div [ngClass]="data | myPipe"></div>

In this approach if you rely on app's state you have to explicitly tell the Angular that this pipe is impure .

IMHO the pipe is preferable. And if it is pure (relies only on provided data and app's state has no impact on it) then it's event more efficient.

you can make use of services

you start by creating a service

export class CSSClassProvider{

   constructor() { }

   getDangerClass(params...) {
         return  { state: "rejected" }
   }
}

and inject your service in your module and use it

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
 @NgModule({

   providers:    [ CSSClassProvider ],
 })
 export class AppModule { }

hope that help.

You can create a file cool-styles.ngclass.ts for example and export your code there.

export const CoolStyles = {
 "someclass" : true,
 "bg-white" : false
};

your file here could include imports for logic checks or some other setting from an env var for example.

If this isn't what you're looking for you could consider using a Service to provide access to the ngClass anywhere.

You can create a Service, but it's more like a utility function. I would create an app.utils.ts in app/ directory.

export function getClass(...) {
    return ....
}

Then in your Component,

import {getClass} from 'app.utils'
...
export class XYZComponent {
   public getClass = getClass // Then you can use getClass in template
}

You can also create AppUtils class that have multiple static utility functions, but creating separate functions instead of having them in a class makes them more tree-shakable.

For the example you provided, an attribute directive with an Input would be the way to go.

Docs: https://angular.io/guide/attribute-directives#pass-values-into-the-directive-with-an-input-data-binding

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM