Comment étendre / hériter des composants?


160

Je voudrais créer des extensions pour certains composants déjà déployés dans Angular 2, sans avoir à les réécrire presque complètement, car le composant de base pourrait subir des modifications et souhaiter que ces modifications soient également reflétées dans ses composants dérivés.

J'ai créé cet exemple simple pour essayer de mieux expliquer mes questions:

Avec le composant de base suivant app/base-panel.component.ts:

import {Component, Input} from 'angular2/core';

@Component({
    selector: 'base-panel',
    template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
    styles: [`
    .panel{
    padding: 50px;
  }
  `]
})
export class BasePanelComponent { 

  @Input() content: string;

  color: string = "red";

  onClick(event){
    console.log("Click color: " + this.color);
  }
}

Voulez - vous que créer un autre composant dérivé alter, par exemple, un comportement des composants de base dans le cas de la couleur par exemple, app/my-panel.component.ts:

import {Component} from 'angular2/core';
import {BasePanelComponent} from './base-panel.component'

@Component({
    selector: 'my-panel',
    template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
    styles: [`
    .panel{
    padding: 50px;
  }
  `]
})
export class MyPanelComponent extends BasePanelComponent{

  constructor() {
    super();
    this.color = "blue";
  }
}

Exemple de travail complet dans Plunker

Remarque: évidemment, cet exemple est simple et pourrait être résolu sinon pas besoin d'utiliser l'héritage, mais il ne vise qu'à illustrer le vrai problème.

Comme vous pouvez le voir dans l'implémentation du composant dérivé app/my-panel.component.ts, une grande partie de l'implémentation a été répétée, et la seule partie réellement héritée était le class BasePanelComponent, mais il @Componentfallait essentiellement répéter complètement, pas seulement les parties modifiées, comme le selector: 'my-panel'.

Existe-t-il un moyen de faire un héritage littéralement complet d'un composant Angular2, en héritant de la classdéfinition des marquages ​​/ annotations, comme par exemple @Component?

Modifier 1 - Demande de fonctionnalité

Demande de fonctionnalité angular2 ajoutée au projet sur GitHub: Extend / Inherit angular2 components annotations # 7968

Modifier 2 - Demande fermée

La demande a été fermée, pour cette raison , que brièvement ne sauraient pas comment fusionner le décorateur sera faite. Nous laissant sans options. Mon opinion est donc citée dans le numéro .


Vérifiez cette réponse stackoverflow.com/questions/36063627/… Cordialement
NicolasB

Ok NicolasB. Mais mon problème est avec l'héritage du décorateur @Component, qui n'est pas appliqué aux métadonnées d'héritage. = /
Fernando Leal

les gens, veuillez éviter d'utiliser l'héritage avec angular. par exemple, la classe d'exportation PlannedFilterComponent étend AbstractFilterComponent implémente OnInit {est très mauvais. Il existe d'autres moyens de partager du code, par exemple des services et des composants plus petits. L'héritage n'est pas la voie angulaire. Je suis sur un projet angulaire où ils ont utilisé l'héritage et il y a des choses qui cassent, comme l'exportation de composants qui héritent de composants abstraits manquant des entrées de la classe abstraite.
robert king

1
utilisez plutôt la projection de contenu, par exemple github.com/angular/components/blob/master/src/material/card/… ne pas utiliser l'héritage
robert king

Réponses:


39

Solution alternative:

Cette réponse de Thierry Templier est une manière alternative de contourner le problème.

Après quelques questions avec Thierry Templier, je suis arrivé à l'exemple de travail suivant qui répond à mes attentes en tant qu'alternative à la limitation d'héritage évoquée dans cette question:

1 - Créer un décorateur personnalisé:

export function CustomComponent(annotation: any) {
  return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);

    var parentAnnotation = parentAnnotations[0];
    Object.keys(parentAnnotation).forEach(key => {
      if (isPresent(parentAnnotation[key])) {
        // verify is annotation typeof function
        if(typeof annotation[key] === 'function'){
          annotation[key] = annotation[key].call(this, parentAnnotation[key]);
        }else if(
        // force override in annotation base
        !isPresent(annotation[key])
        ){
          annotation[key] = parentAnnotation[key];
        }
      }
    });

    var metadata = new Component(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
  }
}

2 - Composant de base avec le décorateur @Component:

@Component({
  // create seletor base for test override property
  selector: 'master',
  template: `
    <div>Test</div>
  `
})
export class AbstractComponent {

}

3 - Sous-composant avec le décorateur @CustomComponent:

@CustomComponent({
  // override property annotation
  //selector: 'sub',
  selector: (parentSelector) => { return parentSelector + 'sub'}
})
export class SubComponent extends AbstractComponent {
  constructor() {
  }
}

Plunkr avec un exemple complet.


3
Je suppose que cela ne sera pas compatible avec le compilateur de modèles hors ligne.
Günter Zöchbauer

@ GünterZöchbauer, je n'ai aucune connaissance du "modèle de compilateur hors ligne" d'Angular2. Mais je pense que ce n'est peut-être pas compatible, et ce serait une alternative. Où le mode "compilateur de modèles hors ligne" d'Angular2 serait-il utile? Tu peux me montrer quelque chose pour mieux comprendre ça? Je peux donc comprendre l'importance de cette compatibilité pour mon projet.
Fernando Leal

Le compilateur de modèles hors ligne (OTC) n'est pas encore fonctionnel même s'il est déjà inclus dans RC.3. OTC analysera les décorateurs et générera du code lors d'une étape de construction lorsque le déployable est généré. OTC permet de supprimer l'analyseur et le compilateur Angular2 qui traitent les décorateurs et les liaisons au moment de l'exécution, ce qui entraîne une taille de code nettement plus petite et une initialisation plus rapide des applications et des composants. OTC deviendra probablement utilisable avec l'une des prochaines mises à jour.
Günter Zöchbauer

1
@ GünterZöchbauer, maintenant je comprends l'importance de maintenir la fonctionnalité compatible avec OTC. Ce sera une pré-compilation de décorateurs angulaires réduisant la surcharge pour initialiser les composants. J'aurais aimé connaître le fonctionnement de ce processus et parce que la solution de cette réponse ne sera pas compatible avec OTC? Comment se passe la pré-compilation des décorateurs? Ayant ces connaissances, nous pourrions penser à quelque chose pour conserver cette alternative fonctionnelle à l'OTC. Merci pour la clarification!
Fernando Leal

24

Angular 2 version 2.3 vient de sortir et inclut l'héritage des composants natifs. Il semble que vous pouvez hériter et remplacer ce que vous voulez, à l'exception des modèles et des styles. Quelques références:


Un "gotcha" se produit ici lorsque vous oubliez de spécifier un nouveau "sélecteur" dans le composant enfant. Vous obtiendrez une erreur d'exécution du genre More than one component matched on this elementsi vous ne le faites pas.
The Aelfinn

@TheAelfinn Ouais: chaque composant doit avoir une spécification complète dans la @Component()balise. Mais vous pouvez partager le .html ou le .css en vous référant au même fichier si vous le souhaitez. Dans l'ensemble, c'est un gros plus.
Daniel Griscom

Dans votre deuxième lien scotch.io/tutorials/component-inheritance-in-angular-2 , l'auteur affirme que les composants héritent des services injectés de dépendance de leurs parents, mon code suggère le contraire. Pouvez-vous confirmer que cela est pris en charge?
The Aelfinn

18

Maintenant que TypeScript 2.2 prend en charge les mixins via les expressions de classe, nous avons une bien meilleure façon d'exprimer des mixins sur des composants. N'oubliez pas que vous pouvez également utiliser l'héritage des composants depuis angular 2.3 ( discussion ) ou un décorateur personnalisé comme indiqué dans d'autres réponses ici. Cependant, je pense que les Mixins ont certaines propriétés qui les rendent préférables pour la réutilisation du comportement entre les composants:

  • Les mixins composent de manière plus flexible, c'est-à-dire que vous pouvez mélanger et assortir des mixins sur des composants existants ou combiner des mixins pour former de nouveaux composants
  • La composition de Mixin reste facile à comprendre grâce à sa linéarisation évidente vers une hiérarchie d'héritage de classe
  • Vous pouvez plus facilement éviter les problèmes avec les décorateurs et les annotations qui affectent l'héritage des composants ( discussion )

Je vous suggère fortement de lire l'annonce TypeScript 2.2 ci-dessus pour comprendre le fonctionnement de Mixins. Les discussions liées dans les problèmes angulaires de GitHub fournissent des détails supplémentaires.

Vous aurez besoin de ces types:

export type Constructor<T> = new (...args: any[]) => T;

export class MixinRoot {
}

Et puis vous pouvez déclarer un Mixin comme ce Destroyablemixin qui aide les composants à garder une trace des abonnements qui doivent être supprimés dans ngOnDestroy:

export function Destroyable<T extends Constructor<{}>>(Base: T) {
  return class Mixin extends Base implements OnDestroy {
    private readonly subscriptions: Subscription[] = [];

    protected registerSubscription(sub: Subscription) {
      this.subscriptions.push(sub);
    }

    public ngOnDestroy() {
      this.subscriptions.forEach(x => x.unsubscribe());
      this.subscriptions.length = 0; // release memory
    }
  };
}

Pour mélanger Destroyabledans un Component, vous déclarez votre composant comme ceci:

export class DashboardComponent extends Destroyable(MixinRoot) 
    implements OnInit, OnDestroy { ... }

Notez que cela MixinRootn'est nécessaire que lorsque vous souhaitez extendune composition Mixin. Vous pouvez facilement étendre plusieurs mixins, par exemple A extends B(C(D)). C'est la linéarisation évidente des mixins dont je parlais ci-dessus, par exemple, vous composez effectivement une hiérarchie d'héritage A -> B -> C -> D.

Dans d'autres cas, par exemple lorsque vous souhaitez composer des Mixins sur une classe existante, vous pouvez appliquer le Mixin comme ceci:

const MyClassWithMixin = MyMixin(MyClass);

Cependant, j'ai trouvé que la première méthode fonctionne le mieux pour Componentset Directives, car ils doivent également être décorés avec @Componentou de @Directivetoute façon.


C'est génial! Merci pour la suggestion. MixinRoot est-il simplement utilisé comme espace réservé de classe vide ici? je veux juste m'assurer que ma compréhension est correcte.
Alex Lockwood

@AlexLockwood ouais, l'espace réservé de classe vide est exactement ce pour quoi je l'utilise. J'éviterais volontiers de l'utiliser mais pour l'instant je n'ai pas trouvé de meilleur moyen de le faire.
Johannes Rudolph

2
J'ai fini par utiliser function Destroyable<T extends Constructor<{}>>(Base = class { } as T). De cette façon, je peux créer des mixins en utilisant extends Destroyable().
Alex Lockwood

1
Cela semble très bien, mais il semble que AoT build (Cli1.3) supprime ngOnDestroy de DashBoardComponent car il n'est jamais appelé. (il en va de même pour ngOnInit)
dzolnjan

merci pour cette solution. Cependant, après une construction de prod avec ionic ou angular-cli, le mixin ne fonctionne pas d'une manière ou d'une autre, comme s'il n'avait pas été étendu.
Han Che

16

mettre à jour

L'héritage des composants est pris en charge depuis la version 2.3.0-rc.0

original

Jusqu'à présent, le plus pratique pour moi est de conserver le modèle et les styles dans des fichiers *html& séparés *.csset de les spécifier via templateUrlet styleUrls, donc c'est facilement réutilisable.

@Component {
    selector: 'my-panel',
    templateUrl: 'app/components/panel.html', 
    styleUrls: ['app/components/panel.css']
}
export class MyPanelComponent extends BasePanelComponent

2
C'est exactement ce dont j'ai besoin. À quoi ressemblerait le décorateur @Component pour BasePanelComponent? Pourrait-il référencer différents fichiers html / css? Pourrait-il référencer les mêmes fichiers html / css référencés par MyPanelComponent?
ebhh2001

1
Cela ne veut pas hériter @Input()et @Output()décorateurs, le fait?
Leon Adler

10

Pour autant que je sache, l'héritage des composants n'a pas encore été implémenté dans Angular 2 et je ne suis pas sûr s'ils ont l'intention de le faire, mais comme Angular 2 utilise du dactylographié (si vous avez décidé de suivre cette voie), vous pouvez utiliser l'héritage de classe en faisant class MyClass extends OtherClass { ... }. Pour l'héritage des composants, je vous suggère de vous impliquer dans le projet Angular 2 en allant sur https://github.com/angular/angular/issues et en soumettant une demande de fonctionnalité!


Compris, je vais essayer dans les prochains jours de me faire une itération sur le projet angular2 et vérifier que la fonctionnalité de requête n'est plus dans les problèmes de projet dans Git et sinon je rédigerai une requête pour la ressource, car cela me semble très intéressant fonctionnalité. Une idée d'arguments supplémentaires pour faire la demande la plus intéressante?
Fernando Leal

1
En ce qui concerne le dactylographié de la ressource d'héritage que j'utilise déjà dans ma solution initiale ( export class MyPanelComponent extends BasePanelComponent), le problème est uniquement dans le cas où les annotations / décorateurs ne sont pas hérités.
Fernando Leal

1
Ouais, je ne sais vraiment pas ce que tu pourrais ajouter. J'aime l'idée d'avoir un nouveau décorateur (quelque chose comme @SubComponent()) qui marque une classe comme sous-composant ou d'avoir un champ supplémentaire sur le @Componentdécorateur qui vous permet de référencer un composant parent dont hériter.
watzon

1
Demande de fonctionnalité angular2 ajoutée au projet sur GitHub: Extend / Inherit angular2 components annotations # 7968
Fernando Leal

9

Laissez-nous comprendre certaines limitations et fonctionnalités clés du système d'héritage des composants d'Angular.

Le composant n'hérite que de la logique de classe:

  • Toutes les métadonnées du décorateur @Component ne sont pas héritées.
  • Les propriétés des composants @Input et @Output sont héritées.
  • Le cycle de vie des composants n'est pas hérité.

Ces caractéristiques sont très importantes à garder à l'esprit, alors examinons chacune d'elles indépendamment.

Le composant n'hérite que de la logique de classe

Lorsque vous héritez d'un composant, toute la logique à l'intérieur est également héritée. Il est à noter que seuls les membres publics sont hérités car les membres privés ne sont accessibles que dans la classe qui les implémente.

Toutes les méta-données du décorateur @Component ne sont pas héritées

Le fait qu'aucune méta-donnée ne soit héritée peut sembler contre-intuitif au début, mais si vous y réfléchissez, cela a en fait un sens. Si vous héritez d'un composant, disons (componentA), vous ne voudriez pas que le sélecteur de ComponentA, dont vous héritez, remplace le sélecteur de ComponentB qui est la classe qui hérite. La même chose peut être dite pour le template / templateUrl ainsi que pour le style / styleUrls.

Les propriétés des composants @Input et @Output sont héritées

C'est une autre fonctionnalité que j'aime vraiment à propos de l'héritage de composants dans Angular. En une phrase simple, chaque fois que vous avez une propriété @Input et @Output personnalisée, ces propriétés sont héritées.

Le cycle de vie des composants n'est pas hérité

Cette partie est celle qui n'est pas si évidente, en particulier pour les personnes qui n'ont pas beaucoup travaillé avec les principes de la POO. Par exemple, supposons que vous ayez ComponentA qui implémente l'un des nombreux hooks de cycle de vie d'Angular comme OnInit. Si vous créez ComponentB et héritez de ComponentA, le cycle de vie OnInit de ComponentA ne se déclenchera pas tant que vous ne l'aurez pas appelé explicitement, même si vous avez ce cycle de vie OnInit pour ComponentB.

Appel des méthodes de composant Super / Base

Afin d'avoir la méthode ngOnInit () de ComponentA fire, nous devons utiliser le mot clé super, puis appeler la méthode dont nous avons besoin, qui dans ce cas est ngOnInit. Le mot-clé super fait référence à l'instance du composant hérité dont dans ce cas sera ComponentA.


5

si vous lisez les bibliothèques CDK et les bibliothèques de matériaux, elles utilisent l'héritage mais pas tant pour les composants eux-mêmes, la projection de contenu est roi de l'OMI. voir ce lien https://blog.angular-university.io/angular-ng-content/ où il est dit "le problème clé avec cette conception"

Je sais que cela ne répond pas à votre question, mais je pense vraiment que l'héritage / l'extension des composants doit être évité . Voici mon raisonnement:

Si la classe abstraite étendue par deux ou plusieurs composants contient une logique partagée: utilisez un service ou même créez une nouvelle classe dactylographiée pouvant être partagée entre les deux composants.

Si la classe abstraite ... contient des variables partagées ou des fonctions onClicketc, alors il y aura duplication entre le html des deux vues de composants étendus. C'est une mauvaise pratique et que le code HTML partagé doit être divisé en composant (s). Ces composants (parties) peuvent être partagés entre les deux composants.

Est-ce que je manque d'autres raisons pour avoir une classe abstraite pour les composants?

Un exemple que j'ai vu récemment était des composants étendant AutoUnsubscribe:

import { Subscription } from 'rxjs';
import { OnDestroy } from '@angular/core';
export abstract class AutoUnsubscribeComponent implements OnDestroy {
  protected infiniteSubscriptions: Array<Subscription>;

  constructor() {
    this.infiniteSubscriptions = [];
  }

  ngOnDestroy() {
    this.infiniteSubscriptions.forEach((subscription) => {
      subscription.unsubscribe();
    });
  }
}

c'était bas parce que dans une grande base de code, infiniteSubscriptions.push()n'a été utilisé que 10 fois. L'importation et l'extension AutoUnsubscribenécessitent en fait plus de code que l'ajout mySubscription.unsubscribe()de la ngOnDestroy()méthode du composant lui-même, ce qui nécessitait de toute façon une logique supplémentaire.


Ok, je comprends votre colocalisation et je conviens que l'agrégation résout presque tous les problèmes qui semblent nécessiter un héritage. Et il est toujours intéressant de considérer les composants comme de petites parties de l'application qui peuvent être ancrées de différentes manières. Mais dans le cas de la question, le problème est que je n'ai pas de contrôle / accès aux modifications dans le composant dont je veux hériter (c'est un troisième composant), alors l'agrégation deviendrait irréalisable et l'héritage serait la solution idéale.
Fernando Leal

pourquoi ne pouvez-vous pas simplement créer un nouveau composant qui encapsule ce composant tiers? Quel est votre composant tiers par intérêt? par exemple <my-calendar [stuff] = stuff> <third-party-calendar [stuff] = stuff> </ ..> </ ..>
robert king

@robertking se répéter est un modèle très faible ... C'est pourquoi vous commencerez à détester votre travail ... au lieu de l'apprécier.
Dariusz Filipiak

Pour ma part, c'est une bonne idée d'étendre les composants au cas où vous voudriez avoir les mêmes paramètres d'entrée / sortie pour un ensemble de composants, afin qu'ils puissent se comporter comme un seul. Par exemple, j'ai plusieurs étapes d'enregistrement (credentialsStep, addressStep, selectBenefitsStep). Ils doivent tous avoir les mêmes options d'entrée (stepName, actionButtons ...) et Outputs (complete, cancel).
Sergey_T

@Sergey_T pourriez-vous envisager un composant avec ng select et projection de contenu? Répéter également quelques entrées ne semble pas que vous économisiez vraiment beaucoup de fonctionnalités TBH.
robert king

2

Si quelqu'un cherche une solution mise à jour, la réponse de Fernando est à peu près parfaite. Sauf que cela ComponentMetadataest obsolète. En utilisantComponent place a fonctionné pour moi.

Le CustomDecorator.tsfichier complet du décorateur personnalisé ressemble à ceci:

import 'zone.js';
import 'reflect-metadata';
import { Component } from '@angular/core';
import { isPresent } from "@angular/platform-browser/src/facade/lang";

export function CustomComponent(annotation: any) {
  return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);

    var parentAnnotation = parentAnnotations[0];
    Object.keys(parentAnnotation).forEach(key => {
      if (isPresent(parentAnnotation[key])) {
        // verify is annotation typeof function
        if(typeof annotation[key] === 'function'){
          annotation[key] = annotation[key].call(this, parentAnnotation[key]);
        }else if(
          // force override in annotation base
          !isPresent(annotation[key])
        ){
          annotation[key] = parentAnnotation[key];
        }
      }
    });

    var metadata = new Component(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
  }
}

Ensuite, importez-le dans votre nouveau sub-component.component.tsfichier de composant et utilisez à la @CustomComponentplace de @Componentceci:

import { CustomComponent } from './CustomDecorator';
import { AbstractComponent } from 'path/to/file';

...

@CustomComponent({
  selector: 'subcomponent'
})
export class SubComponent extends AbstractComponent {

  constructor() {
    super();
  }

  // Add new logic here!
}

Les décorateurs personnalisés ne sont-ils pas fortement découragés? De nombreux autres articles / discussions, cette solution a été marquée comme complètement fausse car AOT ne les prend pas en charge?
TerNovi

2

Vous pouvez hériter de @Input, @Output, @ViewChild, etc. Regardez l'exemple:

@Component({
    template: ''
})
export class BaseComponent {
    @Input() someInput: any = 'something';

    @Output() someOutput: EventEmitter<void> = new EventEmitter<void>();

}

@Component({
    selector: 'app-derived',
    template: '<div (click)="someOutput.emit()">{{someInput}}</div>',
    providers: [
        { provide: BaseComponent, useExisting: DerivedComponent }
    ]
})
export class DerivedComponent {

}

1

Les composants peuvent être étendus de la même manière qu'un héritage de classe dactylographié, simplement que vous devez remplacer le sélecteur avec un nouveau nom. Toutes les propriétés d'entrée () et de sortie () du composant parent fonctionnent normalement

Mettre à jour

@Component est un décorateur,

Les décorateurs sont appliqués lors de la déclaration de classe et non sur les objets.

Fondamentalement, les décorateurs ajoutent des métadonnées à l'objet de classe et qui ne sont pas accessibles via l'héritage.

Si vous souhaitez obtenir l'héritage du décorateur, je vous suggère d'écrire un décorateur personnalisé. Quelque chose comme l'exemple ci-dessous.

export function CustomComponent(annotation: any) {
    return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;

    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);
    var parentParamTypes = Reflect.getMetadata('design:paramtypes', parentTarget);
    var parentPropMetadata = Reflect.getMetadata('propMetadata', parentTarget);
    var parentParameters = Reflect.getMetadata('parameters', parentTarget);

    var parentAnnotation = parentAnnotations[0];

    Object.keys(parentAnnotation).forEach(key => {
    if (isPresent(parentAnnotation[key])) {
        if (!isPresent(annotation[key])) {
        annotation[key] = parentAnnotation[key];
        }
    }
    });
    // Same for the other metadata
    var metadata = new ComponentMetadata(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
    };
};

Référez-vous: https://medium.com/@ttemplier/angular2-decorators-and-class-inheritance-905921dbd1b7


Pourriez-vous illustrer (en utilisant l'exemple de la question) comment cela fonctionnerait-il? Vous pouvez utiliser stackblitz pour développer l'exemple et partager le lien.
Fernando Leal

@Component est un décorateur, les décorateurs sont appliqués lors de la déclaration de classe pas sur les objets.
MAHESH VALIYA VEETIL

Vous avez raison. Les décorateurs ne font aucune différence. Il n'est requis que si le composant de base est utilisé comme composant ailleurs
MAHESH VALIYA VEETIL

0
just use inheritance,Extend parent class in child class and declare constructor with parent class parameter and this parameter use in super().

1.parent class
@Component({
    selector: 'teams-players-box',
    templateUrl: '/maxweb/app/app/teams-players-box.component.html'
})
export class TeamsPlayersBoxComponent {
    public _userProfile:UserProfile;
    public _user_img:any;
    public _box_class:string="about-team teams-blockbox";
    public fullname:string;
    public _index:any;
    public _isView:string;
    indexnumber:number;
    constructor(
        public _userProfilesSvc: UserProfiles,
        public _router:Router,
    ){}
2.child class
@Component({

    selector: '[teams-players-eligibility]',
    templateUrl: '/maxweb/app/app/teams-players-eligibility.component.html'
})
export class TeamsPlayersEligibilityComponent extends TeamsPlayersBoxComponent{

    constructor (public _userProfilesSvc: UserProfiles,
            public _router:Router) {
            super(_userProfilesSvc,_router);
        }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.