angular - Herança de componentes Angular4 com classe abstrata
Quero definir uma classe base para meus componentes compartilharem algumas funcionalidades. Então comecei com:
export abstract class BaseComponent {
protected getName(): string;
}
@Component(...)
export class MyComponent extends BaseComponent {
protected getName(): string {
return "MyComponent";
}
}
Mas depois eu precisei adicionar algumas anotações ao BaseComponent como @HostListener('window:keydown', ['$event']). Então eu tive que adicionar @Component ao BaseComponent para habilitar as anotações do Angular. Tudo estava bem... Até eu tentar compilar no modo de produção com
ng build --prod
:
Não é possível determinar o módulo para a classe BaseComponent
Então eu adicionei BaseComponent ao @NgModule, mas eu tive :
Nenhum template especificado para o componente BaseComponent
Então eu adicionei
@Component({template: ''})
Mas eu tinha :
O argumento do tipo 'typeof BaseComponent' não é atribuível ao parâmetro do tipo 'Type'. Não é possível atribuir um tipo de construtor abstrato a um tipo de construtor não abstrato.
Então eu tive que remover a palavra-chave "abstract" para compilar meu projeto no modo de produção.
Você tem uma solução? Eu não gosto de más concepções!
Resposta #1
Atualização para Angular 10+
A partir do Angular 10, ao usar o compilador IVY, os componentes que são herdados e que contêm funcionalidades do Angular devem ser decorados com um decorador vazio @Directive().
Leia mais sobre isso aqui
Não é necessário adicionar anotações @Component() a classes abstratas ou registrá-las em qualquer módulo.
Pode ser que haja algo errado no seu código que não esteja em conformidade com o que o Angular espera.
Criei um aplicativo de demonstração usando o Angular CLI 1.2.7 com o comando ng new <name> e estendi a classe AppComponent como abaixo.
base.component.ts
import { HostListener } from '@angular/core';
export abstract class BaseComponent {
@HostListener('click')
onClick() {
alert('Click');
}
}
e
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';
}
A classe app.module não foi alterada de forma alguma.
O manipulador de clique localizado no componente base funcionou sem nenhum problema. Uma compilação AOT usando ng build --prod também não apresentou nenhum erro.
Esta demonstração estava usando Angular v5.1.1
