Как использовать субъекты для обмена глобальными данными в angular 6

Я пытался найти лучшее решение для обмена данными между двумя компонентами, имеющими одного и того же родителя.

Я использую степпер из углового материала. Шаг 1 имеет один компонент, а шаг 2 - другой. Что я пытаюсь сделать, так это «щелкнуть» 1 кнопку в компоненте из шага 1 и обновить массив данных, который влияет на компонент на шаге 2.

Это мой код:

Глобальный сервис:

  export class GlobalDataService {
  private reserveSource = new BehaviorSubject<any[]>([]);

  currentReserve = this.reserveSource.asObservable();

  constructor() { }

  changeReserve(reserve: any[]) {
    this.reserveSource.next(reserve)

  }
}

Компонент 1, который пытается обновить:

setSpace(id) {
this.apiObservableService
  .getService('http://localhost:8080/Spaces/' + id)
  .subscribe(
    result => {
      this.space = result;
      this.globaldataservice.changeReserve(result.reserves);
      sessionStorage.setItem('currentSpace', JSON.stringify(result));
    },
    error => console.info(error)
  );

}

Компонент 2, который пытается прочитать и обновить:

ngOnInit(): void {

    this.currentUser = JSON.parse(sessionStorage.getItem('currentUser'));
    this.currentSpace = JSON.parse(sessionStorage.getItem('currentSpace'));

    this.globaldataservice.currentReserve.subscribe(message => this.reserves = message)
    console.info(this.reserves);
  }

В мире rx.net вы могли бы легко сделать это с помощью шаблона FromEvent. Это относится к Angular?

Sentinel 21.05.2018 23:34

Используйте фабрику.

Abr001am 21.05.2018 23:47
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
3
2
2 759
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Откровенно говоря, ваш код должен работать нормально, но вот как я с этим справляюсь, если я что-то пропустил в вашем коде.

GlobalDataStore также должен выдавать BehaviourSubject как Observable, чтобы вы могли подписаться на него.

Также сделайте предмет поведения приватным.

export class GlobalDataService {
  private reserveSource = new BehaviorSubject<any[]>([]);

  get reserveSource() {
       return this.reserveSource.asObservable();
  }
}

Тогда просто подпишитесь на него в компоненте.

В качестве бонуса я также реализую эти функции в своих магазинах (так как я тоже использую BehaviourSubject)

//Gets the last value, that was pushed to the BehaviourSubject
get reserveSourceLastValue() {
   return this.reserveSource.getValue();
}

//Deep clones the last value, if I want a precise copy for form editing buffer
get reserveSourceForEdit() {
    return __lodash.cloneDeep( this.reserveSource.getValue() );
}

СОВЕТ ПРОИЗВОДИТЕЛЬНОСТИ!

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

Прочтите эту статью о том, как изящно отказаться от подписки в компонентах.

Angular / RxJs Когда мне следует отказаться от подписки на `Subscription`

+1 для той строки, в которой вы указали уничтожить подписку, поскольку в большинстве случаев мы все забываем об этом и оставляем ее открытой.

faizan baig 22.05.2018 06:01

Привет, спасибо за повтор. Я пробовал другую версию кода и использую поведенческие субджеты, объекты воспроизведения, сюжеты. К сожалению, я уже пробовал ваше решение до этого сообщения и не работал. Основная проблема, с которой я сталкиваюсь, заключается в том, что подписка не запускается в любом случае.

AngelMdez 22.05.2018 09:24

Хорошо ... Еще одна идея, вы храните свои хранилища в каком-то подмодуле, который вы экспортируете в root? Потому что, если вы предоставите свой магазин в подмодуле, вы создадите 2 магазина. on - это глобальное хранилище, которое внедряется во все, что находится за пределами модуля, а службы, которые используют хранилище внутри базового (не корневого) модуля, используют основное хранилище.

Karl Johan Vallner 22.05.2018 09:29

Обычно console.info («Hello World!») В конструкторе хранилища, затем загружает приложение и перемещается. Если это появляется 2 раза, то вы знаете, что у вас есть 2 одноэлементных магазина с разными данными и наблюдаемыми онлайн!

Karl Johan Vallner 22.05.2018 09:30

Починил это. Я создавал несколько экземпляров глобальной службы, добавляя [поставщиков] к обоим моим компонентам. Удалил это из partent и childs и работал безупречно. Спасибо! Извините за то, что не показал этот порт кода, вы не могли знать об этом.

AngelMdez 22.05.2018 09:32

Другие вопросы по теме