Объект BehaviorSubject не выдает значения

#angular #typescript #rxjs #rxjs-observables

Вопрос:

у меня проблема с выводом значений из объекта поведения после оператора switchMap из родительского компонента в дочерний. Если я вызову реальный http API в консоли.войдите в дочерний компонент, если я вижу только пустой массив [] (значение по умолчанию), но в операторе tap в родительском компоненте, если я консольный.данные журнала я видел массив из 20 элементов, но в дочернем компоненте их нет. Когда я попытался создать макет сервиса и вернуть поддельные данные.

напр.. return of(['item1', 'item2']

Этот случай работает нормально, но когда я переключил только имя службы вызова, он работает неправильно для меня, в tap я вижу данные, а в дочернем вводе-нет.

 import { Component, VERSION } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { AppserviceService } from './appservice.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  name = 'Angular '   VERSION.major;
  refresh$: Subject<void> = new Subject();
  data$: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);

  constructor(private _appService: AppserviceService) {
    this.refresh$
      .pipe(switchMap(() => this._appService.test2()))
      .subscribe(res => {
        console.log('Subscribe:');
        console.log(res);
        this.data$.next(res)
      });

    this.refresh$.next();
  }
}


 

Дочерний компонент

 import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Component({
  selector: 'hello',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <h1>Hello {{ name }}!</h1>
  `,
  styles: [
    `
      h1 {
        font-family: Lato;
      }
    `
  ]
})
export class HelloComponent {
  @Input() name: string;
  @Input() set test(value: BehaviorSubject<any[]>) {
    console.log(value.getValue());
  }
}
 

https://stackblitz.com/edit/angular-ivy-7wezwh?file=src/app/app.component.ts

Вы сталкивались с этой проблемой ? Спасибо.

Комментарии:

1. попробуйте ввести данные журнала консоли перед этой строкой this.childData$.next(data);

2. Попробуйте заменить refresh$ = new Subject(); на refresh$ = new BehaviorSubject();

3. Когда я утешаю. данные журнала, я видел результаты. И я думаю, что тема поведения неверна, потому что мне не нужно какое-либо значение по умолчанию. Но я попробовал это с нулевым значением по умолчанию и тоже не работает. Есть пример на стекблитце. В сервисе у меня есть два API, один макет, второй реальный API. Мок работает нормально, но во-вторых, нет. stackblitz.com/edit/angular-ivy-7wezwh?file=src/app/…

Ответ №1:

Причина в том, что ваш дочерний компонент создается до завершения вашего http-вызова. Прямо сейчас вы принимаете только getValue() первое значение. Если вы хотите BehaviorSubject , чтобы система выдавала новые данные каждый раз, когда они у нее есть, вы можете исправить это, просто добавив оператор асинхронности:

 <hello name="{{ name }}" [test]="data$ | async"></hello>
 
 @Input() set test(value: any[]) {
  console.log(value);
}
 

Теперь каждый раз BehaviorSubject , когда значение имеет новое значение, оно будет передаваться вашему дочернему компоненту

Исправлен стекблитц