1

I have a component that should change its behavior depending on what directive is added to the element. This custom logic are defined in the directives so the component needs not be modified when a new scope/feature is added.

MyComponent
MyDirectiveBase
MyDirective1 extends MyDirectiveBase
MyDirective2 extends MyDirectiveBase

In the component constructor, I want to inject the directive that is applied to the element. I can do this without issue when I know the exact class that will be used, but what I want is any directive that extends from MyDirectiveBase.

How can I tell the DI-framework to allow all subclasses of MyDirectiveBase?

I have tried using an injection token (with multi=true), but that just gave me an array of the classes/functions, not the element instance. Also if no attribute is specified, no directive should be injected.

Sample repo: https://github.com/ulvesked/angular-dependency-inject-directive-subclass-to-component

StackBlitz: https://stackblitz.com/edit/angular-ivy-bihzjv?devtoolsheight=33&file=src/app/app.component.html

ulvesked
  • 429
  • 3
  • 11
  • 1
    I'm too tired to write an actual answer - here is working stackblit: https://stackblitz.com/edit/angular-ivy-up2khd Read up on DI in Angular - especially InjectionToken. Sorry for not writing up full answer. – TotallyNewb Jan 13 '21 at 22:50
  • Thank you. I have read about Injection tokens but apparently not enough. This is helpful! – ulvesked Jan 14 '21 at 08:09

1 Answers1

1

Here is the a sample.

https://stackblitz.com/edit/angular-ivy-tnb5up

The basic idea is make each directive to provide the basic class MyGreetingDirective with implemented class. So HelloComopnent can get different directive instance from Angular DI according to your attribute.

yinnping
  • 146
  • 2
  • This works partly as expected. The correct class is injected into the component, but the directive is instantiated twice, because different injection tokens are used in constructors and template. The template uses MyFormalGreeting and the component constructor uses MyGreeting. It resolves to the same class, but different instances. Check console output on this link https://stackblitz.com/edit/angular-ivy-ctamv8?file=src%2Fapp%2Fdirectives%2Fmy-greeting.directive.ts – ulvesked Jan 18 '21 at 13:25
  • You can change `useClass` to `useExist`. It will make sure using your directive instance which already exist. – yinnping Jan 19 '21 at 02:45