无法将数据从父组件传递到子组件

时间:2020-11-10 15:21:18

标签: javascript angular typescript

您对下面的奇怪问题有任何想法吗?

我正在将数据从父级传递到子级组件,该子级组件是从服务方法返回的,返回的数据为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(不确定是否正确使用了它)。

2 个答案:

答案 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中,无需在设置验证器之前等待组件视图的初始化。