9

I have a solution to the problem of importing static content and using it in a template, but I am not sure it is the right one, so I would like to hear if there is an official/better way of doing it.

This is the example, with relevant parts and my current solution.

constants.ts

export const ELEMENT_TYPES = { FIELD: {...}, GROUP: {...} ...};

component.ts

import {ELEMENT_TYPES} from "./constants";

@Component({
   ...
   templateUrl:"./template.html"
})
export class myComponent{
   public type = ELEMENT_TYPES.GROUP;

   public get ELEMENT_TYPES() {
      return ELEMENT_TYPES;
   }

   public isOfType(matchType){
      return this.type === matchType;
   }
   ...
}

template.html

<div *ngIf="isOfType(ELEMENT_TYPES.FIELD)">
   ...
</div>

Of course in the real implementation type is set from another place (it is in a metadata object sent down via input)

What I am concerned about is the use of the same name for the property getter as the imported constant name. But if I don't create a getter I will not have access to the constant in the template. And I want to access the constant ELEMENT_TYPES with the same name in the template as in the component class.

This problem is the same for classes, functions and variables imported in this way. (We have static library classes (not services) for instance that sometimes needs to be used from the templates)

And of course I am open to a whole other way of seeing the problem, is there for instance a better way to package the constants and classes (we don't have functions imported this way) to access them from the template and the component classes via the same name.

Rickard Staaf
  • 2,650
  • 2
  • 14
  • 14
  • 1
    Does https://stackoverflow.com/questions/39193538/how-to-bind-static-variable-of-component-in-html-in-angular-2 help ? – oomer Feb 14 '22 at 10:46

1 Answers1

0

I can think of four approaches. I can't really justify this, it's my opinion. Maybe someone else can give insights that go above the one unnecessary reference. I'd go for 3 or 4.

1. Instance variable

import {ELEMENT_TYPES} from "./constants";

class MyComponent {
  readonly ElementTypes: typeof ELEMENT_TYPES = ELEMENT_TYPES;
}
<div *ngIf="isOfType(ElementTypes.FIELD)">
   ...
</div>

The references stay the same, but each instance has an identical variable containing a reference to the import.

2. Static variable

import {ELEMENT_TYPES} from "./constants";

class MyComponent {
  private static readonly _ElementTypes: typeof ELEMENT_TYPES = ELEMENT_TYPES;
  get ElementTypes() {
    return MyComponent._ElementTypes;
  }
}
<div *ngIf="isOfType(ElementTypes.FIELD)">
   ...
</div>

The reference to the import is now a static, but you need a getter to access it. Which means you might as well use

3. Getter

import {ELEMENT_TYPES} from "./constants";

class MyComponent {
  get ElementTypes() {
    return ELEMENT_TYPES;
  }
}
<div *ngIf="isOfType(ElementTypes.FIELD)">
   ...
</div>

No surplus references anywhere, all consumer code uses the identical object from the import.

4. Move the functionality into the code

import {ELEMENT_TYPES} from "./constants";

class MyComponent {
  private elementType: ELEMENT_TYPE = ELEMENT_TYPE.FIELD;

  isOfTypeField() {
    return this.elementType === ELEMENT_TYPE.FIELD;
  }
}
<div *ngIf="isOfTypeField()">
   ...
</div>
Randelung
  • 356
  • 4
  • 10