Pesquisa de site

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

Artigos relacionados