【问题标题】:Angular: Cannot read property 'sendClassForm' of undefined inside ng-template of NgbModalAngular:无法读取 NgbModal 的 ng 模板内未定义的属性“sendClassForm”
【发布时间】:2019-08-29 20:30:59
【问题描述】:

好的,首先,我已经疯狂地搜索了这个问题,并找到了一些解决方案(一些在此处进行了解释),但它们都没有解释一种有效的方法来做到这一点。所以,我来了……

这是关于什么的

我正在创建一个使用 ng-bootstrap 的模式。我制作了一个表单组件以在其他页面中重新使用它。我把这个组件放在模态里。我需要从Parent 中获取这个组件的变量和方法,所以我在Parent 的组件中设置了一个ViewChild 变量并将其设置为Child Component。

当我打开模式时,组件显示没有问题。当我单击“创建”按钮时,问题就来了。当用户单击“创建”按钮时,父级(包含模式)执行子级的方法来发送表单,但父级无法访问子级的方法,因为它未定义,即使模式已经打开。

我已经尝试过的

我尝试将 Child 组件放在 ng-template 之外,它工作得很好,但我需要它在模态中。

我还尝试将指令上带有#id 的组件传递给父方法,以便执行子方法。它可以工作,但会使代码更脏,并在未来带来更多问题。 (这实际上是我自己在这个实现中遇到了更多问题的未来。)

如果有人想知道它会带来什么样的问题,我需要将更多的组件嵌套到子组件中,因为这个“孙子”组件仍在 ng-template 中,问题重复出现,现在我必须编写代码又脏了……

代码(Stackblitz 应用程序)

这是我制作的 Stackblitz 应用程序。我保持它非常简单,并排除了与问题无关的不必要的代码部分。 Stackblitz App

我收到的消息错误

这是我收到的错误消息:

ERROR TypeError: Cannot read property 'sendClassForm' of undefined

我读过当 ng-template 还没有被渲染时(比如模态还没有打开)你会得到这个undefined 错误,但我不明白为什么它已经打开时仍然发生。

Angular 版本:8.1.2

"@ng-bootstrap/ng-bootstrap": "^5.1.0"

【问题讨论】:

    标签: angular undefined-behavior ng-bootstrap viewchild ng-template


    【解决方案1】:

    感谢@yurzui 坚持他的解决方案,我想出了另一个我认为几乎与拥有 ViewChild 相同但没有问题的解决方案。

    这里是 Stackblitz 代码,如果您想立即看到它,而不是我的解释。

    Stackblitz App

    父组件

    我设置了一个属性,与 ViewChild 相同,但删除了 ViewChild 部分。

    classFormComponent: ClassFormComponent; // No 'ViewChild(...)' part
    

    并且还创建了一个方法来在需要时将子组件的引用保存到上面的变量中。

    // This method will be called by the ClassFormComponent when it gets ready to be used by the Parent.
    saveReference( classFormComponent: ClassFormComponent ) {
        this.classFormComponent = classFormComponent;
    }
    

    父 HTML

    然后,我为app-class-form 设置了一个监听器,这样当孩子准备好时,它可以通过调用上面解释的父母方法告诉父母。

    <app-class-form (componentIsReady)="saveReference( $event )"></app-class-form>
    

    子组件

    孩子有一个输出事件发射器。

    @Output() componentIsReady: EventEmitter<ClassFormComponent> = new EventEmitter();`
    

    并且这个事件是在ngOnInit生命周期阶段发出的。

    ngOnInit() {
    
        // At this point, child component is born and it's ready to be used by the parent.
        this.componentIsReady.emit(this);
    }
    

    这样,父级可以访问子级的方法和属性。

    我说这是我所拥有的解决方案的逆解,因为现在孩子准备好后到达父母,只有这样,父母才会保存对它的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      • 1970-01-01
      相关资源
      最近更新 更多