父组件中的多个可观察变量与子组件中的一个可观察变量

时间:2018-06-27 15:47:52

标签: angular rxjs observable

让我们假设我们有两个模型PlayerWorld,我们希望在一个共同的视图中显示玩家的信息及其世界信息。我们通过两个可观察对象playerObservableworldObvservable获得这些信息。我们定义PlayerComponent(父),PlayerInformationComponent(子)和WorldInformationComponent(子)。

我想知道哪种解决方案最有效:

  • PlayerComponent中,我同时加载玩家和世界信息:

    // player.component.ts
    forkJoin([playerObservable, worldObservable])
        .subscribe(([player, world]) => {
            this.player = player;
            this.world = world;
        });
    

    并将每个信息提供给相应的组件:

    // player.component.html
    <app-player [player]="player"></app-player>
    <app-world [world]="world"></app-world>
    

    每个子组件中都有一个ngIf

    // player-information.component.html
    <div *ngIf="player">...</div>
    
    // world-information.component.html
    <div *ngIf="world">...</div>
    

    各有一个@Input

    // player-information.component.ts
    @Input() public player: Player;
    
    // world-information.component.ts
    @Input() public world: World;
    
  • 每个子组件都加载自己的信息:

    // player-information.component.ts
    playerObservable.subscribe((player) => { this.player = player; });
    
    // world-information.component.ts
    worldObservable.subscribe((world) => { this.world = world; });
    

    然后:

    // player.component.html
    <app-player></app-player>
    <app-world></app-world>
    

2 个答案:

答案 0 :(得分:1)

您的情况没有太大区别,我只是建议根据需要这些数据的组件来决定,如果在父级和子级中-获取父级并与子级组件共享,如果仅在子级中共享-您可以在这些孩子中分别获取数据。

但是

例如,如果您有许多子组件,则可以通过*ngFor动态地重复某些操作,因此我强烈建议获取父组件中的数据并与子组件共享。否则,您将拥有50个组件和50个订阅,这将大大降低应用程序的运行速度。

答案 1 :(得分:1)

使用services共享数据
Angular将组件与服务区分开来,以提高模块化和可重用性。 and It's Good Practice to Delegate complex component logic to services

  

摘自 Angular样式指南
将组件中的逻辑限制为仅   视图所需的内容。所有其他逻辑应委托给   服务。

     

将可重用逻辑移至服务,并保持组件简单和   专注于他们的预期目的。

     

为什么?逻辑可以放在多个组件中时由多个组件重用   服务并通过功能公开。

     

为什么?可以在单元测试中更轻松地隔离服务中的逻辑,   同时可以轻松地模拟组件中的调用逻辑。

     

为什么?删除依赖项并从   组件。

     

为什么?使组件保持苗条,修剪和集中。

如果您的目标是多播数据,请使用RXJS的SubjectBehaviorSubject Subject充当源Observable与许多observers之间的桥梁/代理,使多个observers可以共享相同的Observable执行。

BehaviorSubject优于Subject

  1. 它将始终返回订阅时的当前值-无需调用 onnext().
  2. 它具有getValue()函数来提取最后一个值作为原始数据。
  3. 它确保组件始终接收最新数据。
  4. 您可以使用asobservable()从行为主题中观察到      BehaviorSubject上的方法。
  5. Subject vs BehaviorSubject

服务

 private firstResponse=new BehaviorSubject<any>('');
     private secondResponse=new BehaviorSubject<any>('');
          CurrentDatafirst = this.firstResponse.asObservable();
          CurrentDatasecond = this.secondResponse.asObservable();
    getdata(){
       forkJoin([playerObservable, worldObservable])
    .subscribe(([player, world]) => {

    this.firstResponse.next(player),
    this.secondResponse.next(world)
  })
    });
   }

组件1:

ngOnInit()
{
  this.service.CurrentDatafirst.subscribe(//value=>your logic);
  this.service.CurrentDatasecond.subscribe(//value=>your logic)

}

第二部分:

 ngOnInit()
    {
      this.service.CurrentDatafirst.subscribe(//value=>your logic);
      this.service.CurrentDatasecond.subscribe(//value=>your logic)

    }

RxJS Subjects for human beings

BehaviorSubject in Angular

Live Demo


------------------------------------------- ------------------------------------------

您还可以使用shareReplay运算符为多个观察者共享一个http请求,并采取相应的行动。
您必须意识到http返回可观察到的寒冷,并且 当冷observable具有多个subscribers时,将为每个subscriber重新发射整个数据流。每个订户变得独立,并获得自己的数据流

为避免HTTP请求重复使用shareReplay运算符。
服务

 public response$:Observable<any>
    getdata(){
               forkJoin([playerObservable, worldObservable]).pipe(sharReplay(1));
            }

   fetchdata()
           {
              this.response$;
            }

Component1:

 ngOnInit()
    {
      this.service.fetchdata().subscribe(//value=>your logic);


    }

Component2:

    ngOnInit()
    {
      this.service.fetchdata().subscribe(//value=>your logic);


    }

Live Demo