1

I'm trying to migrate an old library of Angular components to standalone components.

A number of the components have a lot in common, so I use a superclass for all of the common behavior. At least as I was accustomed to doing things, the superclass of a @Component shouldn't be another @Component, but rather a @Directive.

The start of the superclass looks like this:

// @dynamic
@Directive()
export abstract class DigitSequenceEditorDirective<T> implements
    AfterViewInit, ControlValueAccessor, OnInit, OnDestroy, Validator {
// ...

And one the subclass components starts like this:

// @dynamic
@Component({
  selector: 'tbw-time-editor',
  animations: [BACKGROUND_ANIMATIONS],
  templateUrl: '../digit-sequence-editor/digit-sequence-editor.directive.html',
  styleUrls: ['../digit-sequence-editor/digit-sequence-editor.directive.scss', './time-editor.component.scss'],
  providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TimeEditorComponent), multi: true },
              { provide: NG_VALIDATORS, useExisting: forwardRef(() => TimeEditorComponent), multi: true }]
})
export class TimeEditorComponent extends DigitSequenceEditorDirective<number> implements OnInit {
// ...

The problem now, porting this to Angular 19 and trying to use a standalone design, is that the HTML for the directive contains some CommonModule features like [ngClass] and [ngStyle]. (There are also uses of *ngIf and the like, but those I can get rid of using @if, @for, etc.)

A non-functional recommendation by Google AI for using CommonModule features in a directive looks like this:

import { Directive, Input } from '@angular/core';
    import { NgIf } from '@angular/common';
    
    @Directive({
      selector: '[appMyStandalone]',
      standalone: true,
      imports: [NgIf] // Can't be done! No `imports` field! (I'd have NgClass and NgStyle here if this worked)
    })
    export class MyStandaloneDirective {
      @Input() appMyStandalone: boolean = false;
    }

If I can't use imports with a directive, how do I resolve the red squiggly line stuff below?

enter image description here

1 Answer 1

1

The directive never contains the imports used in HTML, it always exists on the parent component.

The content of the decorator is never inherited in angular, only the class properties and methods.

The reason we use @Directive({ ... }) is so that you can use angular features like model, input, etc.

So add the common module imports in the child component, the parent directive decorator contents are never used anyway.

// @dynamic
@Component({
  selector: 'tbw-time-editor',
  animations: [BACKGROUND_ANIMATIONS],
  templateUrl: '../digit-sequence-editor/digit-sequence-editor.directive.html',
  styleUrls: [
    '../digit-sequence-editor/digit-sequence-editor.directive.scss', 
    './time-editor.component.scss'
  ],
  providers: [
    { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TimeEditorComponent), multi: true },
    { provide: NG_VALIDATORS, useExisting: forwardRef(() => TimeEditorComponent), multi: true }
  ],
  imports: [
    ...
    NgIf
    ...
  ],
})
export class TimeEditorComponent extends DigitSequenceEditorDirective<number> implements OnInit {
// ...
Sign up to request clarification or add additional context in comments.

3 Comments

Is the Intellij IDEA syntax highlighting just wrong, and the flagged HTML belonging to the directive will work regardless, so long as the subclass components have the needed imports?
@kshetline if the component that contains this html has the necessary imports and the angular compiler compiles the code, then the problem might be with intellij
This works! Thanks. Also, once I had added the necessary imports to both subclasses IDEA took the error highlighting away from the superclass HTML... actually pretty damn clever syntax highlighting to do that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.