【问题标题】:Best Practice: Generic Component with different services最佳实践:具有不同服务的通用组件
【发布时间】:2018-06-17 16:31:26
【问题描述】:

假设我们有一个 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(...)
  }
}

但我希望有一些可能更简洁的最佳实践技巧。提前致谢!

【问题讨论】:

    标签: angular2-services generic-programming angular2-components


    【解决方案1】:

    这里的最佳做法是将组件与显示层分开,将容器与服务层分开。所以你的表格组件应该只发出在表格上发生的事情的信息,例如:

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

    感谢您,您可以轻松更改容器中的逻辑,并且表格组件不需要知道数据会发生什么。表格组件应该只发出事件,而不关心它们会发生什么。将服务传递给组件并不是一个好主意。请记住,始终将服务层(容器)和组件层(仅接受输入并在输出上发出事件)分开

    【讨论】:

      猜你喜欢
      • 2023-01-18
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多