I want to define a base class for my components to share some features. So i've began with :
export abstract class BaseComponent {
protected getName(): string;
}
@Component(...)
export class MyComponent extends BaseComponent {
protected getName(): string {
return "MyComponent";
}
}
But after i needed to add some annotations to BaseComponent like @HostListener('window:keydown', ['$event'])
. So i had to add @Component
to BaseComponent
to enable angular annotations. Everything was good... Until i tried to compile in production mode with
ng build --prod
:
Cannot determine the module for class BaseComponent
So i've added BaseComponent
to @NgModule
, but i had :
No template specified for component BaseComponent
So i've added
@Component({template: ''})
But i had :
Argument of type 'typeof BaseComponent' is not assignable to parameter of type 'Type'. Cannot assign an abstract constructor type to a non-abstract constructor type.
So i had remove the "abstract
" keyword to compile in production mode my project.
Do you have a solution? I dislike bad conception!
As of Angular 10, when using the IVY compiler, components that are inherited, and which contain Angular functionality, must be decorated with an empty @Directive()
decorator.
Read more about it here
There's no need to add @Component()
annotations to abstract classes or register them to any module.
It could be that there's something wrong within your code that does not conform to what Angular expects.
I created a demo application using Angular CLI 1.2.7 with the ng new <name>
command and extend the AppComponent class as below.
base.component.ts
import { HostListener } from '@angular/core';
export abstract class BaseComponent {
@HostListener('click')
onClick() {
alert('Click');
}
}
and
app.component.ts
import { Component } from '@angular/core';
import { BaseComponent } from './base.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent extends BaseComponent {
title = 'app';
}
The app.module class was not changed in any way.
The click handler located in the base component worked without any problems. A AOT compilation using ng build --prod
also did not give any errors.
This demo was using angular v5.1.1