web-dev-qa-db-fra.com

Héritage de Composants Angular4 avec une classe abstraite

Je souhaite définir une classe de base pour que mes composants partagent certaines fonctionnalités. J'ai donc commencé par:

export abstract class BaseComponent {
    protected getName(): string;
}

@Component(...)
export class MyComponent extends BaseComponent {
    protected getName(): string {
        return "MyComponent";
    }
}

Mais après j'ai eu besoin d'ajouter quelques annotations à BaseComponent comme @HostListener('window:keydown', ['$event']). J'ai donc dû ajouter @Component À BaseComponent pour activer les annotations angular. Tout était bon ... Jusqu'à ce que j'essaye de compiler en mode production avec

ng build --prod

:

Impossible de déterminer le module pour la classe BaseComponent

J'ai donc ajouté BaseComponent à @NgModule, Mais j'avais:

Aucun modèle spécifié pour le composant BaseComponent

Donc j'ai ajouté

@Component({template: ''})

Mais j'avais:

L'argument de type 'typeof BaseComponent' n'est pas assignable au paramètre de type 'Type'. Impossible d'affecter un type de constructeur abstrait à un type de constructeur non abstrait.

J'avais donc retiré le mot-clé "abstract" pour compiler en mode production mon projet.

Avez-vous une solution? Je n'aime pas les mauvaises conceptions!

16
Chklang

Il n'est pas nécessaire d'ajouter des annotations @Component () aux classes abstraites ou de les enregistrer dans n'importe quel module.

Il se peut que quelque chose qui ne va pas dans votre code ne soit pas conforme à ce que Angular attend.

J'ai créé une application de démonstration en utilisant Angular CLI 1.2.7 avec le ng new <name> commande et étends la classe AppComponent comme ci-dessous.

base.component.ts

import { HostListener } from '@angular/core';

export abstract class BaseComponent {
    @HostListener('click')
    onClick() {
        alert('Click');
    }
}

et

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';
}

La classe app.module n'a pas été modifiée.

Le gestionnaire de clics situé dans le composant de base a fonctionné sans problème. Une compilation AOT utilisant ng build --prod n'a également donné aucune erreur.

Cette démo utilisait angular v5.1.1

25
JeanPaul A.