BehaviorSubject возвращает неправильные данные - PullRequest
0 голосов
/ 21 апреля 2020

Я пытался использовать BehaviorSubject, в своем небольшом приложении, в котором хранится состояние выбранных флажков. Вот ссылка на приложение Код Stackblitz

У меня есть список флажков стран (Мексика, Канада, США и др. c.) На странице, чье состояние мне нужно сохранить , Для этого я использую Angular Сервис с BehaviorSubject. Всякий раз, когда я выбираю несколько флажков и затем нажимаю кнопку «Сохранить» на странице, я передаю проверенные данные о состоянии флажка службе, а затем служба передает эти данные обратно компоненту через BehaviorSubject.

Компонент будет передавать данные о состоянии флажков в службу только в том случае, если нажата кнопка «Применить», но когда я установлю несколько флажков, а затем перейду на другую страницу (например, домашнюю страницу) в приложении, используя ссылку маршрутизатора, и когда я вернусь к На странице меню со всеми флажками объект BehaviorSubject из службы возвращает флажки, которые были нажаты. Это странно, не правда ли? Что мне здесь не хватает?

Примечание. Я вызываю метод storeData, только если пользователь нажимает кнопку сохранения. Даже если я прокомментирую вызов метода storeData в методе save, я вижу такое же поведение. Это должно что-то делать с BehaviorSubject? Я использую BehaviorSubject, чтобы служба передавала предыдущие данные, когда компонент загружается, и подписывается на options$

. Вот код: component. html

    <div class="countries" *ngFor="let item of data">
      <input
        [id]="item"
        type="checkbox"
        [checked]="selectedOption[item]"
        [value]="item"
        (change)="onToggle($event)"
      />
      <label [for]="item">{{ item }}</label>
    </div>

    <button (click)="saveOptions()">Save</button>

component.ts

    data = [
        "India",
        "Australia",
        "USA",
        "Brazil",
        "Canada",
        "South Africa",
        "UK",
      ];

      selectedOption = {};

      constructor(private dataService: DataService, private router: Router) {}

      ngOnInit(): void {
        this.dataService.options$.subscribe((data) => {
          console.log(data);
          this.selectedOption = data;
        });
      }

      onToggle(event) {
        this.selectedOption[event.target.value] = event.target.checked;
      }

      saveOptions() {
        this.dataService.storeData(this.selectedOption);
        this.router.navigate(["/home"]);
      }

data.service.ts

    selectedOptions = {};
      optionsAction = new BehaviorSubject<any>(this.selectedOptions);
      options$ = this.optionsAction.asObservable();

      constructor() {}

      storeData(data) {
        this.selectedOptions = data;
        this.optionsAction.next(data);
      }

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Я бы go по этому маршруту:

service.ts

selectedOptions: any = {};

private _selectedOptionsAction$ = new BehaviorSubject<any>({
    selectedOptions: this.selectedOptions,
});

getSeletedOptionsData(): Observable<any> {
    return this._selectedOptionsAction$.asObservable();
}

storeSeletedOptionsData(data: any): void {
    this.selectedOptions = data.selectedOptions;
    this._selectedOptionsAction$.next(data);
}

component.ts

ngOnInit(): void {
    this.sub = this._megamenu.getSeletedOptionsData().subscribe((data:any) => {
      console.log(data);
      this.selectedOptions = data.selectedOptions;
    })
}

apply(): void {
    this._megamenu.storeSeletedOptionsData({
        selectedOptions: this.selectedOptions
    });
}
0 голосов
/ 21 апреля 2020

Вы подписываетесь на наблюдаемое selectedOptions$ и устанавливаете значения для субъекта _selectedOptionsAction, но они отличаются:

 ngOnInit(): void {
    this.sub = this._megamenu.selectedOptions$.subscribe(data => {  //this observable never emitted values
      console.log(data);
      this.selectedOptions = data.selectedOptions;
    })
  }

Не может ли эта подписка быть для _selectedOptionsAction субъекта (я имею в виду next () и subscribe () только из одной темы, зачем добавлять путаницу)?

...