您对下面的奇怪问题有任何想法吗?
我正在将数据从父级传递到子级组件,该子级组件是从服务方法返回的,返回的数据为Observable<DemoModel>
。但是,当子组件正在加载时,数据是不确定的,并且仅在ngAfterViewInit
之后填充(我也尝试通过此方法获取数据,但是数据仍然是不确定的)。因此,我也尝试应用一些ngOnchanges
方法,但是问题更多的是与在加载子组件时未准备好从父组件检索的数据有关(我也尝试使用异步等,而不是订阅。子组件加载时,我应该如何获取数据以使其准备就绪?
父项和子项如下所示:
父母补偿
<child-component
[courses]="courses|async"
>
</child-component>
courses: any;
this.service.listCourses().subscribe((course: Course) => {
this.courses = course;
});
儿童组合
private courses: any;
@Input()
set data(data: any) {
this.courses.next(data);
}
myControl = new FormControl('');
ngAfterViewInit() {
// >>> THIS THROWS ERROR AS this.courses is undefined
this.myControl.setValidators([
Validators.required,
forbiddenNamesValidator(this.courses)
]);
}
我也尝试在html中使用一些*ngIf
,但是由于方法中使用了this.courses
参数,因此检查html中的数据没有任何意义。
该问题可能是由于订阅方法引起的,但我也尝试使用了promise(不确定是否正确使用了它)。
答案 0 :(得分:1)
第一种方式:添加ngIf
来检查您是否有数据。
<child-component [courses]="courses" *ngIf="courses.length > 0"> </child-component>
第二种方式:如果要使用async
,则不要在组件中订阅它。
<child-component [courses]="courses$ | async" *ngIf="(courses$| async)?.length > 0"> </child-component>
组件:
courses$: Observable<any>;
this.courses$ = this.service.listCourses().pipe(shareReplay());
答案 1 :(得分:1)
async
管道data
,并使用了setter来对应为数组的变量调用.next
-即.next
将不存在。 / li>
父母补偿
<child-component
[courses]="courses"
>
</child-component>
courses: any;
this.service.listCourses().subscribe((course: Course) => {
this.courses = course;
});
Child Comp
@Input() courses: any;
listCourses
是异步的这意味着courses
不一定会在调用ngAfterViewInit
时有值,并且很可能会引发类似的错误。
我可以建议解决以下问题:
<child-component
*ngIf="courses?.length"
[courses]="courses"
>
</child-component>
然后,您不必等待ngAfterViewInit
,而只需等待ngOnInit
。
ngOnInit(): void {
this.myControl.setValidators([
Validators.required,
forbiddenNamesValidator(this.courses)
]);
}
将列表从父母传递给孩子,我应该使用可观察的/应允的/数组等吗?
这完全取决于您,我更喜欢在处理可观察对象时使用async
管道,因为那样我就不必担心取消订阅。
<child-component
[courses]="courses | async"
>
</child-component>
courses = this.service.listCourses()
我认为无需为子组件中的课程使用get / set,因为列表不会更改
在处理变化的数据时,您甚至不必使用get / set。 Angular会为您更新@Input
数据,因此除非明确需要该功能,否则您不必担心使用get / set。
我应该在
this.myControl.setValidators([]}
还是onInit
中调用afterViewInit
和filter方法
无需将验证器的设置转移到afterViewInit
中,无需在设置验证器之前等待组件视图的初始化。