5

我想将一个值传递给子组件。这个值是一个 Observable,所以我使用异步管道。

<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>

我不想更改测试类型Observable并订阅它。我想直接接收最终值。而且我根本不想修改编辑组件。

使用ChangeDetectorRef手动触发变化检测器不是

@Input() test$:Observable

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

我还制作了这个stackblitz来检查所有组件钩子之间的值变化。

4

4 回答 4

11

asyncnull当尚未发出任何值时,管道将返回Observable。因此,test子组件中的值为:

  • undefined在构造函数中,因为@Input()在此状态下未分配变量
  • null之后(例如第一个onChanges钩子或onInit钩子),当 Observable 没有发出任何值时
  • value当 Observable 发出新值时

现在,您应该仅在test变量不null带时创建子组件*ngIf,或者正确处理可空的子组件的状态test(例如,在为空时添加进度条test)。这个选择由你。

于 2020-05-08T15:17:35.077 回答
9

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

于 2020-05-08T14:38:31.467 回答
2

您可以像这样在模板中创建变量:

test$ | async; let test;

然后稍后您可以检查:

*ngIf='test'

如果是真的那么你可以渲染你的子组件。

于 2020-05-08T14:24:43.380 回答
1

更简单的解决方案:

(test$ | async) || defaultTestValue
于 2022-01-26T16:27:33.327 回答