【问题标题】:Angular 6 FormGroup.disable() method is not working with my template driven NgFormAngular 6 FormGroup.disable() 方法不适用于我的模板驱动的 NgForm
【发布时间】:2018-12-12 01:05:15
【问题描述】:

当我尝试在 Angular 6 应用程序中的 formGroup 上使用 disable 方法时,我在浏览器控制台中收到此错误:

TypeError: this.personForm.disable 不是函数

虽然方法是mentioned in the documentation & 甚至 VS Code 都建议使用此快照。

我的代码在这里:

// ... many parts skipped, the form here is template driven 
// but still personForm is a FormGroup , 
// I am trying to disable the whole FormGroup with all child elements
@ViewChild('personForm') personForm: FormGroup;

        if (true) {
       // if I console.log here the form, I can see it is created already
         console.log(this.personForm);              
// output of console.log is 
// NgForm {submitted: false, _directives: Array(0), ngSubmit: EventEmitter, form: FormGroup}

         this.personForm.disable();
        }

这里有什么问题?

更新 1:

我创建了一个堆栈闪电战来显示问题

here is the link for that demo

更新 2: 由于初始加载时错误未显示,如果您删除 this.firstStepForm.disable(); 并重写它,您将收到错误,但无论如何行为不正确,表单字段未按预期禁用

另外,在 stackblitz 中刷新浏览器部分会显示错误的snackbar

【问题讨论】:

  • 你的 if 条件到底是在哪里检查的?在 NgOnInit 中?
  • @monogate 是的,在那里检查过
  • 您可以尝试实现 AfterViewInit 并将您的代码放入 ngAfterViewInit 中吗?
  • 我会试试这个,我还检查了 FormGroup 是由 console.log 创建的,它是在调用之前创建的(请检查问题中的代码,我已经更新了)跨度>
  • 不幸的是,如果我将 disable() 放在 ngAfterViewInit 中,我仍然会遇到同样的错误

标签: angular typescript angular6 angular-forms


【解决方案1】:

您使用模板驱动方法创建的表单对象的类型是 NgForm 而不是 FormGroup

ngForm 对象内部有一个form 属性,它实际上是FormGroup 类型。

所以你应该这样做

this.personForm.form.disable()

编辑:

您必须将代码移动到 AfterViewChecked 生命周期挂钩事件,因为您的 formGroup 不会准备好 ngAfterViewChecked() 被触发。

ngAfterViewChecked() {
      console.log(this.personForm.form);    
      this.personForm.form.disable(); 
      this.cdr.detectChanges();  
} 

并且还推迟更改检测以避免使用 ChangeDetectorRef 的表达式更改错误。

DEMO

【讨论】:

  • 谢谢你的回答,其实它是一个FormGroup,你可以在我的代码中看到类型,你这里使用的方式是响应式FormGroup,我的是模板驱动的FormGroup。我添加了 stackblitz 示例以更好地显示问题
  • 但我没有看到您提到的堆栈闪电战中有任何错误。
  • 是的,当然,奇怪的是它没有给出错误但仍然没有禁用表单,我已经在本地和 stackblitz stackblitz.com/edit/angular-nf9jog?file=app/app.component.ts进行了测试
  • 将你的代码移动到AfterViewChecked生命周期钩子并推迟更改检测以避免表达式更改错误。
  • 很好的解决方案,感谢您提供的非常有用的帮助,我有点害怕这些钩子,因为它们看起来有点太多但它确实有效,谢谢
【解决方案2】:

我发现了这个错误的原因:

这个表单是使用 ngForm 在 html 模板中制作的,然后 我使用 ViewChild 来获取 typescript 文件中的表单,我注意到我做了那个 FormGroup 类型的对象,但 ngForm 与 FormGroup 不同(在我的用例中并不清楚),这就是为什么 FormGroup 禁用方法不适用于 ngForm

注意:

(VS 代码建议它作为我的变量类型是 FormGroup,这会误导编辑器给我这个建议)

感谢所有试图提供帮助的人。

更新:

如果有人像我一样不愿意依赖detectChanges() & 基于 Amit 的优秀答案,我们可以在 AfterContentChecked 中禁用 NgForm 以避免使用 detectChanges()

  // instead of disabling here & using cdr.detectChanges()

  // ngAfterViewChecked() {
  //     console.log(this.personForm.form);    
  //     this.personForm.form.disable(); 
  //     this.cdr.detectChanges();  
  // } 

  // we can put our disable here
  ngAfterContentChecked() {
    this.personForm.form.disable();
  }

Stackblitz demo

【讨论】:

    猜你喜欢
    • 2016-09-02
    • 1970-01-01
    • 2017-10-18
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多