将元素添加到Angular2 +中的rxjs BehaviorSubject或数组的Subject

时间:2018-09-18 17:15:32

标签: angular service rxjs behaviorsubject

我从教程here的“无关组件:与服务共享数据”部分中了解了如何在Angular的无关组件之间共享数据。

我看到了这个示例如何处理他们试图在其组件之间共享的字符串,但是我的数据类型稍微复杂一些:

也就是说,我认为我的BehaviorSubject应该看起来像这样:

private currentPopulationSource: BehaviorSubject<Population> = new BehaviorSubject<Population>(new Population(new Array<Organism>()));

我的人口模型只是一系列生物的容器:

import { Organism } from './organism.model';

export class Population {
  private individuals: any;
  constructor(individuals: Organism[]){
     this.individuals = individuals;
  }

  getIndividuals(){
    return this.individuals;
  }
}

我有一个生物实例,我们称其为organic1。

我想将其添加到“人口”模型中包装的“个人”数组中,并且我希望多个不相关的组件订阅“人口BehaviorSubject”(目前,我的“ PulseManagerManager”中现在有private currentPopulation = this.currentPopulationSource.asObservable();正如我在本教程中看到的那样,声明了currentPopulationSource。

我不清楚向我的currentPopulationSource添加生物体1的语法是什么(.next()在这里似乎没有意义)。

如果我希望不断增长的数组成为发射的东西,也许BehaviorSubject不是在这里做出的最合适的选择?如果有更好的选择(ReplaySubject?),我不太知道如何实现。

我的人口管理服务:

import { Injectable } from '@angular/core';
import { Organism } from './organism.model';
import { Population } from './population.model';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PopulationManagerService {
  private currentPopulationSource: BehaviorSubject<Population> = new BehaviorSubject<Population>(new Population(new Array<Organism>()));
  currentPopulation = this.currentPopulationSource.asObservable();
  constructor() { }

  addOrganismToPopulation(organism: Organism){
    this.currentPopulationSource.next(new Population(new Array<Organism>(organism))); //This does not work
    // this.currentPopulation.getIndividuals().push(organism); //This did not work either, because currentPopulation is of type Observable<Population> rather than of type Population
  }
}

在我的组件中:

let testIndividual: Organism = this.individualGenService.makeIndividual("green", "blue");
    this.popManager.addOrganismToPopulation(testIndividual);
    this.popManager.currentPopulation.subscribe(results =>{
      console.log(results.getIndividuals()); //returns undefined
    });

当前返回未定义。

非常感谢您提供有关此问题的帮助。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,您想在种群对象内的生物列表中添加一个新生物。这是在使用行为主题时。

在您的示例中,您可以执行以下操作。

addOrganismToPopulation(organism: Organism){
    this.currentPopulationSource
        .pipe(take(1))
        .subscribe((population: Population) => {
            this.currentPopulationSource.next(
                new Population([...population.getIndividuals(), organism]))
            )
        });
  }

那么我们在这里做什么。为了将新生物添加到当前种群中,我们需要了解生物列表。因此,我们赞成拥有人口的可观察物。在订阅中,我们创建了一个新的人口实例。在创建新实例时,我们与新物种一起创建了一系列已知生物。然后,我们将新的/更新的种群添加到流中。

请注意,我仅获取流的一个值take(1)。这是因为当我们要计算新的生物列表时,我们仅需要当前种群。这也可以防止不必要的内存泄漏。发生一个事件后,take运算符将从流中取消订阅。

用很少的信息很难说行为主题是否是您的用例的好选择。