【问题标题】:Angular 7 - View Child Still Returns as Undefined After Child Component is InitializedAngular 7 - 在子组件初始化后,视图子仍然返回未定义
【发布时间】:2019-04-09 14:12:46
【问题描述】:

我有一个组件正在利用 View Change 订阅来监视表单复选框中的更改。当复选框更改为 true 时,子组件的表单将设置为禁用,当复选框为 false 时启用。每次在选中复选框时尝试调用 View Child 函数时,都会返回以下错误: 错误类型错误:无法读取未定义的属性“enableForm”。

我在这里找到的讨论此问题的帖子似乎指向子组件被 ngIf 隐藏,但在我的实例中并非如此。

我已经在控制台记录了各种 Angular 生命周期事件、NgOnInit、NgAfterViewInit、createForm() 等,它们都会在表单初始化时返回。我还可以将一个值传递到子组件中,该值将禁用 Init 上的子表单字段,以便该部分正常工作。但我无法让 View Child 通过同一个组件实例工作。

在这里我初始化我的 View Child:

@ViewChild('effectiveDateComponent') effectiveDateComponent: any;

在这里,我正在侦听复选框中的表单更改(称为“futureDelete”:

    this.editForm.get('futureDelete').valueChanges.subscribe(val => {
      if (val === false) {
        this.effectiveDateComponent.disableForm();
        this.deleteButtonDisableFlag = false;
      }
      if (val === true) {
        this.effectiveDateComponent.enableForm();
        this.deleteButtonDisableFlag = true;
        this.editForm.controls.dateSearch.get('date').valueChanges.subscribe(val => {
          if (val) {
            this.deleteButtonDisableFlag = false;
          }
          if (!val) {
            this.deleteButtonDisableFlag = true;
          }
        });
      }
    });

这是我的 HTML 组件调用:

<app-datetimepicker #effectiveDateComponent [disabled]="true" [dateField]="'effectiveDate'" (dateEmit)="receiveDateEmit($event)" [placeholder]="'yyyy-mm-dd'">Effective Date</app-datetimepicker>

我希望调用函数 disableForm() 或 enableForm(),但我收到以下错误:ERROR TypeError: Cannot read property 'enableForm' of undefined.

【问题讨论】:

  • 子组件初始化后能否尝试调用此方法..即可以在 ngAfterViewInit() 中调用它?
  • 我认为我在孩子初始化后调用它。我已经在各种生命周期钩子上设置了控制台日志,它们都在触发。
  • 尝试在 settimeout 函数中调用你的函数? setTimeout(() => yourfunction(),1000)
  • 我已经尝试过了,但我仍然抛出了同样的错误。
  • 嗯好吧!!..作为一种解决方法,您可以做的是,在父组件中有一个变量,该变量可以在您的函数中设置,该函数订阅复选框的 valuechanges。这个变量可以设置为子组件的输入,在子组件中,您需要在输入变量上订阅 ngOnChanges 以查看变量是否已更改,然后使用它来启用和禁用表单。类似这样:stackoverflow.com/questions/44702370/…

标签: angular typescript


【解决方案1】:

作为一种解决方法,您可以做的是,在父组件中设置一个变量,该变量可以在您的函数中设置,该函数订阅复选框的值更改。该变量可以设置为子组件和子组件中的输入您需要在输入变量上订阅 ngOnChanges 以查看变量是否已更改,然后使用它来启用和禁用表单。类似这样:Angular 2 : ViewChild is undefined on parent

【讨论】:

    【解决方案2】:

    我认为您的代码是在解决 ViewChild 之前执行的,也许您只需要在 enableForm() 和 disableForm(); 方法周围添加一个 if (this.effectiveDateComponent){}

    【讨论】:

    • 感谢您的建议。它会导致整个代码块被跳过,我想这证明了你的观点是 View Child 没有解决?
    • 也许你的模板文件中有一个 *ngIf ?
    • 我的模板文件中有 10 个,但我很确定没有一个包含有问题的组件。
    • 代码部分:this.editForm.get('futureDelete').valueChanges 在哪里执行?在构造函数中? ngOnInit() 方法?
    • 在ngOnInit()中调用。
    【解决方案3】:

    您可以按组件引用它。如果你的&lt;app-datetimepicker&gt; 组件类是class AppDatetimepicker,那么你可以试试这个:

    @ViewChild(AppDatetimepicker) effectiveDateComponent: AppDatetimepicker;
    

    【讨论】:

    • 返回以下错误:未捕获的引用错误:未定义有效日期组件。我认为引号在语法上是必要的?
    • 你是对的。我在阅读整个答案之前发布了。我之后立即更新,但您必须在我更新之前看到。
    • 没问题,感谢您的帮助。您编辑的代码返回我原来的错误:ERROR TypeError: Cannot read property 'enableForm' of undefined.
    【解决方案4】:

    您需要将此订阅放在 ngAfterViewInit 生命周期挂钩中。

    ngAfterViewInit生命周期钩子的描述,根据Angular documentation:

    Angular 初始化组件的视图和子组件后响应 views / 指令所在的视图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-26
      • 1970-01-01
      • 2022-01-19
      • 2017-05-19
      • 1970-01-01
      • 2020-05-11
      • 2020-12-17
      • 2016-08-16
      相关资源
      最近更新 更多