假设我们有一个TableComponent。TableComponent的目的是显示超级英雄并删除/添加它们。为此,它使用HeroService。
TableComponent {
constructor() {
heroService: HeroService
}
getList() {
this.heroService.getHeroes().subscribe(...)
}
addCharacter(character: Character) {
this.heroService.postHero(character).subscribe(...)
}
removeCharacter(character: Character) {
this.heroService.deleteHero(character).subscribe(...)
}
}
现在我们想为我们的超级反派使用相同的 TableComponent。反派服务已经存在并可以使用。此外,超级英雄和超级反派尽管存在分歧,但共享同一类。唯一不同的是他们的服务。实现它最干净的方法是什么?
我的第一个想法是扩展这两种服务,例如:
tableOptions {
getList: this.getHeroes,
addObject: this.postHero,
deleteObject: this.deleteHero
}
并修改组件,例如:
TableComponent {
Input() service; // HeroService or VillainService
getList() {
this.service.tableOptions.getList.subscribe(...)
}
addCharacter(character: Character) {
this.service.tableOptions.addObject(character).subscribe(...)
}
removeCharacter(character: Character) {
this.service.tableOptions.deleteObject(character).subscribe(...)
}
}
但我希望有一些可能更干净的最佳实践技巧。提前感谢!
此处的最佳做法是将组件与显示层分开,将容器与服务层分开。因此,您的表组件应该只发出表上发生某些事情的信息,例如:
TableComponent {
@Input() data;
@Output() addCharacterClicked = new EventEmitter();
@Output() removeCharacterClicked = new EventEmitter();
addCharacter(character: Character) {
this.addCharacterClicked.emit(character);
}
removeCharacter(character: Character) {
this.removeCharacterClicked.emit(character);
}
}
例如,如果您想在一个表中显示英雄和恶棍,那么您可以在容器层中使用此组件:
@Component({
template: `<app-table-component
[data]="characters"
(removeCharacterClicked)="onRemoveCharacterClicked($event)">
</app-table-component>`
}
export class CharactersTableContainer {
characters: Character[] = [];
constructor(private heroService: HeroService,
private villainService: VilliansService) { }
ngOnInit() {
this.heroService.getHeroes().subscribe(heros => this.characters = this.characters.concat(heros));
this.villainService.getVillians().subscribe(villains => this.characters = this.characters.concat(villains));
}
// similiar method to add character
onRemoveCharacterClicked(character: Character) {
if (character instacnceof Hero) {
this.heroService.removeHero(character).subscribe(response => {
// when backend reponds without error remove character from local list
this.removeCharacter(character);
});
} else {
this.villainService.removeVillian(character).subscribe(response => {
this.removeCharacter(character);
});
}
}
private removeCharacter(character: Character) {
// implement method for removing item from this.characters list
}
}
感谢这一点,您可以轻松更改容器中的逻辑,表组件不需要知道数据会发生什么。表组件应该只发出事件,而不关心它们会发生什么。将服务传递给组件不是好主意。请记住始终将服务层(容器(和组件层分开(仅接受输入并在输出上发出事件(