Déclarer un composant de type générique
Est-il possible de déclarer un composant avec un type générique dans Angulaire 4?
Le code suivant provoque les erreurs de compilation:
export class MyGenericComponent<T> implements OnInit {
@Input() data: BehaviorSubject<T[]>;
//...
}
L'erreur lors de l'exécution de ng serve
est:
ERROR in C:/.../my-generic.module.ts (5,10): Module '"C:/.../my-generic.component"' has no exported member 'MyGenericComponent'.
Exemple:
L'exemple suivant est une tentative de mettre en œuvre un générique tableau de données où @Input() data
les changements d'un composant " l'appel de cette composante à l'autre.
La question est peut BehaviorSubject<any[]>
être changé à BehaviorSubject<T[]>
où T
serait le type générique passés au composant?
@Component({
selector: 'my-data-list',
templateUrl: './data-list.component.html',
styleUrls: ['./data-list.component.css']
})
export class DataListComponent implements OnInit {
@Input() data: BehaviorSubject<any[]>;
@Output() onLoaded = new EventEmitter<boolean>();
private tableDataBase : TableDataBase = new TableDataBase();
private dataSource : TableDataSource | null;
constructor() { }
ngOnInit() {
this.tableDataBase.dataChange = this.data;
this.dataSource = new TableDataSource(this.tableDataBase);
this.onLoaded.emit(true);
}
}
class TableDataBase {
dataChange: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);
get data(): any[] {
return this.dataChange.value;
}
}
class TableDataSource extends DataSource<any> {
constructor(private tableDataBase: TableDataBase) {
super();
}
connect(): Observable<any[]> {
return Observable.of(this.tableDataBase.data);
}
disconnect() {}
}
- Comment le cadre de savoir ce que l'argument générique devrait être pour le composant?
- Quel est le problème que vous essayez de résoudre ce problème?
- Je suis en train de mettre en œuvre un composant générique que les listes de données. Le type de modèle de données peut changer en fonction de la page à l'aide de ce composant. J'ai édité ma question pour donner un exemple, là où je suis en utilisant le type générique de la classe
- Je comprends l'idée d'une classe générique, mais comment un composant de faire cela? Sûrement les liaisons seront différentes pour chaque T? Bien sûr, vous pouvez extraire des méthodes communes pour une super-classe, mais au-delà, il est difficile de savoir ce que vous attendez.
- Tu veux dire que c'est un mauvais concept de travailler avec des composants génériques? Techniquement, j'ai pu travailler avec le type de tout à la place d'un type générique, mais serait-ce une bonne pratique?
- Ce n'est pas vraiment clair ce que vous essayez d'atteindre, d'où le commentaire ci-dessus. Sans le contexte, comme un exemple de deux le béton
T
s que vous souhaitez à l'abstrait, c'est probablement un XY problème (voir par exemple xyproblem.info). - J'ai juste ajouté un exemple dans mon post, j'espère qu'elle pourra aider
Vous devez vous connecter pour publier un commentaire.
Vous pouvez également accéder au paramètre de Type par le biais de la ViewChild comme ceci:
T
type de l'argument de laBarComponent
? On ignore toujours à quoi vous attendez-vous à recevoir comme argument, quandBarComponent
est instancié? Il est pertinent d'utiliser des génériques de la classe de béton lorsque vous êtes en contrôle de son instanciation (de sorte que vous pouvez contrôler ce que l'argument de passer). Mais dans le cas de la composante - c'est l'angle de cadre lui-même qui instancie - et le cadre n'est pas au courant de votre paramètre et ne sera pas en mesure de passer à quelque chose de faire sensVous pouvez le déclarer, mais ne peut pas l'utiliser directement. Vous pouvez faire quelque chose comme ceci:
...extends Form<ModelOne>
, je suis à la recherche de quelque chose commeexport class ModelOneForm extends Form<T>
, et ce code génère une erreur de compilation avec le messageCannot find name 'T'
@Componet?
?Vous pouvez envisager de cette façon. Créer une interface pour les données telles que les suivantes:
Transformer les données que vous souhaitez ajouter à la liste pour se conformer à l'interface et donc peut être interprétée par le ListDataComponent. Votre ListDataComponent peut alors dresser la liste des données selon les propriétés de l'interface.