интервал трубопровода, наблюдаемый и передаваемый в качестве входных данных, поскольку асинхронный канал не отображается в шаблоне - PullRequest
0 голосов
/ 10 июля 2019

Скажем, у меня есть некоторые данные, которые извлекаются откуда-то непрерывно; эти данные обрабатываются и передаются через Input (), который используется асинхронным каналом внутри дочернего компонента that-s * ngFor'ed;

наблюдаемое может быть

getObservable(param: string): Observable<string> {
    return timer(1000)
    .pipe(
      map(v => {
        console.log(v);
        return param;
      } )
    )
  }

, который передается в качестве ввода в список дочерних компонентов

<hello *ngFor="let hi of hellos" [name]="getObservable(hi)"></hello>

, который является Наблюдаемым, который управляется через async трубу

<h1>Hello {{name | async}}!</h1>

https://stackblitz.com/edit/angular-51mxua

  1. Почему я не получаю эти данные в компоненте?
  2. Что я могу сделать, чтобы получить данные в компоненте, используя этот подход (иначе не изменять компонент hello, а исправлять его в восходящем направлении, предпочтительно не сохраняя состояние в родительском компоненте)?

Ответы [ 2 ]

3 голосов
/ 10 июля 2019

это не работает из-за того, как угловые трассы изменяют обнаружение.Он постоянно повторяет эту функцию getObservable () снова и снова и отменяет / повторную подписку, поэтому фактически никогда не достигает этого тайм-аута 1000 мс.

сделайте это вместо:

observable$;

constructor() {
  this.observable$ = this.getObservable();
}

и передайте наблюдаемый $ компоненту.Эта функция обнаружения изменений также является причиной того, что вы вообще никогда не должны помещать вызовы функций в шаблоны.это риск для производительности.

Есть много способов сделать это, но обычно вам нужно убедиться, что ваше наблюдаемое назначение выполняется только один раз, и это не произойдет при вызове функции шаблона.

основываясь на ваших изменениях, вы бы сделали это следующим образом:

constructor() {
  this.hellos = this.hellos.map(hello => 
                                Object.assign(hello, {observable$: this.getObservable(hello)});
}

<hello *ngFor="let hi of hellos" [name]="hi.observable$"></hello>

вы могли бы также придумать какую-то систему передачи функции и ее аргументов дочернему элементу:

export class HelloComponent implements OnInit  {
  @Input() param: any;
  @Input() fn$: (param: any) => Observable<string>;
  name: Observable<string>;

  ngOnInit() {
    this.name = this.fn$(this.param);
  }
}

в родительском шаблоне:

<hello *ngFor="let hi of hellos" [fn$]="getObservable" [param]="hi"></hello>

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

0 голосов
/ 10 июля 2019

Вы должны настроить свой AppComponent следующим образом:

export class AppComponent  {

  name = 'Angular';
  obs$: Observable<string>;

  constructor() {
    this.obs$ = this.getObservable();
  }

  getObservable(): Observable<string> {
    return timer(1000)
    .pipe(
      map(v => {
        console.log(v);
        return 'this should show right';

      } )
    )
  }

}

И такой шаблон:

<hello [name]="obs$"></hello>

Смотрите обновленный стек: https://stackblitz.com/edit/angular-crvjrf?file=src/app/app.component.html

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