想根据 Angular 中的条件加载父组件后访问子组件对象

Want to access child component object after parent component loaded based on condition in Angular

我的 angular 应用程序中有一个父页面,我在其中实现了 UI 步分页和 4 个子组件。

父组件:CustomerMain.ts

基于数据填充,我将前进到下一个子组件并从父组件在该组件中加载适当的数据。

第 1 步。 创建了 CustomerMain 组件并调用 API 以在单个服务中获取所有 4 个子组件数据。

@ViewChild("childBasicDetils")
  childBasicDetils: BasicDetils;
@ViewChild("childJobDetails")
  childJobDetails: JobDetails;
@ViewChild("childLocationDetils")
  childLocationDetils: LocationDetils;
@ViewChild("childInsTermsDetails")
  childInsTermsDetails: InsTermsDetails;

viewBasicDetils: boolean = true;
viewJobDetails: boolean = false;
viewLocationDetils: boolean = false;
viewInsTermsDetails: boolean = false;
res: any;

getSFCCustomerDetails(obj) {
    this.portService.getSFCCustomerDetails(obj).subscribe(res => {
       console.log(res)
       this.res = res;
       //Fill 1st Component data like below
       this.childBasicDetils.customerDetails = this.res.customerDetails;
    }
}

第 2 步。 加载第一个子组件(BasicDetils.ts)并从父数据中填充与该组件相关的所有数据。

步骤 3. 更新 1 个子组件中的一些记录并按 "Next" 并加载 2nd 子组件并尝试填充来自父组件的所有数据。

步骤 3 我无法访问我通过 @ViewChild 分配的子组件。

出现以下错误:

core.js:1673 ERROR TypeError: Cannot read property 'setJobDataResults' of undefined at AddCustomer.push../src/app/customer/add-customer/add-customer.component.ts.AddCustomer.showHideComponents (add-sweep-customer.component.ts:429) at SafeSubscriber._next (add-customer.component.ts:283) at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196) at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (Subscriber.js:134)

我知道原因是第一次加载所有子组件不加载只加载第一个组件并根据用户输入我隐藏第一个子组件并加载第二个子组件等等直到所有子组件被覆盖。

Show/Hide 子组件如下:

showHideComponents(index) {
    switch (index) {
      case 1:
        this.viewBasicDetils = true;
        this.viewJobDetails = false;
        this.viewLocationDetils = false;
        this.viewInsTermsDetails = false;
        break;
      case 2:
        this.viewBasicDetils = false;
        this.viewJobDetails = true;
        this.viewLocationDetils = false;
        this.viewInsTermsDetails = false;
      case 3:
        this.viewBasicDetils = false;
        this.viewJobDetails = false;
        this.viewLocationDetils = true;
        this.viewInsTermsDetails = false;
        break;
      case 4:
        this.viewBasicDetils = false;
        this.viewJobDetails = false;
        this.viewLocationDetils = false;
        this.viewInsTermsDetails = true;
        break;
      default:
        break;
    }
  }

所以基本上在调用子组件方法和传递数据时出错,如下所示:

//Fill 2st Component data like below
this.childJobDetails.setJobDataResults(this.res.jobDetails);

我的 HTML 如下所示:

<form class="customForm" *ngIf="viewBasicDetils" style="margin-top: 30px;">
  <add-basicdetils #childBasicDetils></add-basicdetils>
</form>

<div *ngIf="viewJobDetails" style="margin-top: 30px;">
    <add-jobDetails #childJobDetails [isIncludeCriteria]="true" [isEdit]="isEdit" (onDealIdEmit)="isDealId($event)"></add-jobDetails>
</div>

<div *ngIf="viewLocationDetils" style="margin-top: 30px;">
    <add-location-detils #viewLocationDetils [isIncludeCriteria]="false" [isEdit]="isEdit" (addedSLE)="isSLE($event)"></add-location-detils>
</div>

<add-insterms-details #childInsTermsDetails [atcIDCustName]="atcIDCustName" *ngIf="viewInsTermsDetails" (onAtcBackClick)='backCustomerDefinition($event)'></add-insterms-details>

如果我打印那个 ViewChild 对象,它总是给我 未定义的组件对象

请指导我如何从 Parent 访问第二个子组件。

提前致谢!

如果您使用 Angular 中的 *ngIf 结构指令,它不会呈现 DOM 中的元素,直到条件为 true,这就是您的原因正在获取 undefined @ViewChild 对象。

要解决您的问题,您可以使用 HTMLhidden 属性,它呈现 DOM 中的所有元素但它不会显示给用户。

例子-

<div [hidden]="!viewJobDetails" style="margin-top: 30px;">
    <add-jobDetails #childJobDetails [isIncludeCriteria]="true" 
    [isEdit]="isEdit" (onDealIdEmit)="isDealId($event)"></add-jobDetails>
</div>

希望这会有所帮助!

可能对 OP 不再有用,但它可能会帮助遇到同样问题的人。

我遇到了同样的问题,我通过创建一个 ViewChildren 解决了它。

@ViewChildren(MyChildComponent) myViewChilds: QueryList<MyChildComponent>;

然后,我会听取我的 QueryList 上的任何更改。

  ngAfterViewInit(): void {
      this.myViewChilds.changes.subscribe(res => {
          // Here I can access my child components.
          console.log(res.first);
          res.forEach(child => {
              console.log(child);
          }
      });
  }

也许不是最干净的解决方案,但至少它让我保持 *ngIf.