#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
, когда значение имеет новое значение, оно будет передаваться вашему дочернему компоненту