asyn c pipe отправляет нулевое значение дочернему компоненту - PullRequest
0 голосов
/ 08 мая 2020

Я хочу передать значение дочернему компоненту. это значение является Observable, поэтому я использую asyn c pipe.

<child [test]="test$ | async"></child>

test $ - это обычная наблюдаемая переменная, которая выдает значения через определенный период времени (3000 мс), имитируя запрос API на сервер.

this.test$=timer(3000).pipe(
      mapTo("value")      
 )

в дочернем компоненте, я просто хочу проверить test значение

@Input() test: any;

constructor(){
    console.log("child/test", this.test); //null
    setTimeout(()=>console.log("child/test (timeout)", this.test),4000) //value

   if(this.test){
     //maintain and check `this.test`
     //this code will not run, because at this point `this.test` is null.
     //we don't know the exact time that `this.test` will have a value
     //this causes that `this.test` is wrong

      this.checked=true 
     }
  }

<div *ngIf="checked">{{test}}</div>

Я не хочу менять тип теста на be Observable и подписывайтесь на него. Я хочу получить окончательное значение напрямую. и я вообще не хочу изменять компонент редактирования.

использование ChangeDetectorRef для ручного запуска детектора изменений не

@Input() test$:Observable

constructor(){
  this.test$.subscribe(v=>this.test=v)
}

Я также сделал это stackblitz , чтобы проверить изменение значения среди всех крючков компонента.

Ответы [ 3 ]

2 голосов
/ 08 мая 2020

async pipe вернет null, если Observable еще не отправил значение. Итак, значение test в дочернем компоненте:

  • undefined в конструкторе, потому что @Input() переменные не назначаются в этом состоянии
  • null после этого ( например, first onChanges hook или onInit hook`), когда Observable не передает никакого значения
  • value когда Observable испускает новое значение

Теперь вы должны либо создавать дочерний компонент только тогда, когда test переменная не равна null с *ngIf, или правильно обрабатывать состояние дочернего компонента с обнуляемым test (например, добавлять индикатор выполнения, когда test равно нулю). Выбор за вами.

1 голос
/ 08 мая 2020

app.component. html

<ng-container *ngIf=(test$ | async) as test; else defaultTmpl>
    <child [test]="test"></child>
</ng-container>
<ng-template #defaultTmpl>Default Template<ng-template>

Для получения дополнительной информации, пожалуйста, посмотрите: https://ultimatecourses.com/blog/angular-ngif-async-pipe

0 голосов
/ 08 мая 2020

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

test$ | async; let test;

, затем вы можете проверить:

*ngIf='test'

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

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