【发布时间】:2021-03-16 16:34:00
【问题描述】:
我正面临着我不理解的情况。我有一个父组件(示例中为 app.component),它从 API 获取其数据作为可观察对象
然后使用异步管道将这些数据传递给子 (hello.component)。
然后那个孩子接收输入,但是当 ngOnInit 在孩子中运行时,输入是null。
我不明白为什么,也不知道如何使输入成为 API 的实际返回值。 app.component 中对detectChanges() 的调用是触发子项更改检测的绝望尝试,但这不会重新运行ngOnInit,所以它有点没有实际意义。我把它留在那里是因为这就是我正在使用的实际代码的样子。
我知道这段代码很糟糕。不是我写的。不幸的是,我正在使用的组件就是这样,我无法重构它,因为你猜对了,没有单元测试。我正在努力清理它,但现在我必须按原样重用该组件。
Stackblitz:https://stackblitz.com/edit/angular-ivy-rw1xte?devtoolsheight=33&file=src/app/hello.component.ts
// app.component.ts
import { ChangeDetectorRef, Component, VERSION } from "@angular/core";
import { interval, Observable, of } from "rxjs";
import { mapTo, tap } from "rxjs/operators";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
public name$: Observable<any> = of({});
constructor(private cdRef: ChangeDetectorRef) {}
public ngOnInit() {
this.name$ = interval(3000).pipe(
mapTo(() => {
first: "Eunice";
}),
tap(() => this.cdRef.detectChanges())
);
}
}
<!-- app.component.html -->
<hello [name]="name$ | async"></hello>
<p>
Start editing to see some magic happen :)
</p>
// hello.component.ts
import { Component, Input } from "@angular/core";
@Component({
selector: "hello",
template: `
<div *ngIf="name">
<h1>Hello {{ this.name.first }}!</h1>
<h1>{{ greetings }}</h1>
</div>
`,
styles: [
`
h1 {
font-family: Lato;
}
`
]
})
export class HelloComponent {
@Input() name: { first?: string }
public greetings: string = "";
public firstName: string = "";
public async ngOnInit() {
console.log('name:',this.name); // name: null
if (this.name) {
// this conditional is always false because this.name is always null
// and so this never runs.
console.log("got name");
this.firstName = this.name.first || "fallback";
this.greetings = await new Promise(resolve =>
resolve("how do you do, ${firstName}?")
);
}
}
}
【问题讨论】:
标签: javascript angular rxjs