Добавьте элементы в rxjs BehaviorSubject или Subject массива в Angular2 + - PullRequest
0 голосов
/ 18 сентября 2018

Я читал о том, как обмениваться данными между несвязанными компонентами в 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;
  }
}

У меня есть экземпляр Организма, назовем его «организм1».

Я хотел бы добавить его в массив индивидуумов, обернутый в модели Population, и я бы хотел, чтобы несколько несвязанных компонентов подписались на BehaviorSubject для населения (в настоящее время у меня есть private currentPopulation = this.currentPopulationSource.asObservable(); в моем PopulationManagerService сразу после моего объявления currentPopulationSource, какЯ видел в уроке).

Мне неясно, какой будет синтаксис для добавления организма1 к моему currentPopulationSource (.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 голосов
/ 18 сентября 2018

Если я правильно понимаю, вы хотите добавить новый организм в список организмов, который находится внутри популяционного объекта.Это при использовании предмета поведения.

В вашем примере вы можете сделать следующее.

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

Итак, что мы здесь делаем.Чтобы добавить новый организм к текущей популяции, нам нужно знать список организмов.Поэтому мы подписываемся на наблюдаемую, которая держит население.Внутри подписки мы создаем новый экземпляр населения.При создании нового экземпляра мы создаем массив уже известных организмов вместе с новым.Затем мы добавляем новое / обновленное заполнение в поток.

Обратите внимание, что я принимаю только одно значение потока, take(1).Это потому, что в тот момент, когда мы хотим рассчитать новый список организмов, нам нужна только текущая популяция.Это также предотвращает нежелательную утечку памяти.Оператор take отписывается от потока в момент, когда прошло одно событие.

Является ли тема поведения хорошим выбором для вашего варианта использования, трудно сказать с минимумом информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...