簡體   English   中英

無法將數據從父組件傳遞給子組件

[英]Cannot pass data from Parent to Child component

你對下面這個奇怪的問題有什么想法嗎?

我將數據從父組件傳遞到子組件,該子組件從返回數據為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中的數據沒有任何意義。

問題可能是subscribe方法導致的,但是我也嘗試過使用promise(不知道是不是我用的好)。

第一種方式:添加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());

您當前的實現有一些問題:

  • 在您的父組件中,課程是一個數組(我假設)而不是可觀察的 - 無需使用async管道
  • 在您的 Child 組件中,您將輸入字段命名為data ,並使用 setter 對應該是數組的變量調用.next - 即.next存在。

以下應該修復您當前的實現

母公司

<child-component
    [courses]="courses" 
>
</child-component>

courses: any;

this.service.listCourses().subscribe((course: Course) => {
  this.courses = course;
});

兒童補償

@Input() courses: any;

需要注意的是listCourses是異步的

這意味着當ngAfterViewInit時,不一定保證courses具有值,並且可能會拋出類似的錯誤。

我可以建議解決這個問題如下:

<child-component
    *ngIf="courses?.length"
    [courses]="courses" 
>
</child-component>

然后您不必等待ngAfterViewInit ,而只需等待ngOnInit

ngOnInit(): void {
    this.myControl.setValidators([
        Validators.required,
        forbiddenNamesValidator(this.courses)
    ]);
}

注釋

將列表從父級傳遞給子級,我應該使用 observable/promise/array 等嗎?

這完全取決於您,我更喜歡在處理 observable 時使用async管道,因為這樣我就不必擔心取消訂閱我的訂閱了。

<child-component
    [courses]="courses | async" 
>
</child-component>

courses = this.service.listCourses()

我認為沒有必要對子組件中的課程使用 get/set,因為列表不會改變

在處理更改的數據時,您甚至不一定需要使用 get/set。 Angular 會為您更新@Input數據,因此您無需擔心使用 get/set 除非您明確需要該功能。

我應該在onInitafterViewInit調用this.myControl.setValidators([]}和過濾器方法afterViewInit

無需將驗證器設置轉移到您的afterViewInit ,您無需在設置驗證器之前等待組件的視圖初始化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM