TypeError:this.form._updateTreeValidity 不是函数

Posted

技术标签:

【中文标题】TypeError:this.form._updateTreeValidity 不是函数【英文标题】:TypeError: this.form._updateTreeValidity is not a function 【发布时间】:2017-04-15 08:21:33 【问题描述】:

我目前正在使用 Angular Forms 版本 2.0.0 并尝试使用内部的联系表单与我们联系。

在 ContactComponent 加载后,我立即得到:

例外:this.form._updateTreeValidity 不是函数

    我已经看到其他一些堆栈帖子建议使用 FormGroup 而不是 FormBuilder 来初始化组件构造函数中的表单对象现在是新 API 的标准,所以我已经更新了。

    我导入了 ReactiveFormsModule 和 FormsModule 以及所有与表单相关的组件,但错误似乎与模块无关。

    我的 TypeScript 没有在编译时抛出错误,而且 Visual Studio Intellisense 似乎能够很好地找到所有 FormGroup 函数,那么为什么会在运行时发生这种情况?...

我的代码:

contact.component.ts:

import  Component, Input, ViewChild  from '@angular/core';
import  ApiService  from '../../../services/api.service';
import  ModalComponent  from 'ng2-bs3-modal/ng2-bs3-modal';
import  Router, ActivatedRoute, Params  from '@angular/router';
import  FormsModule, ReactiveFormsModule, FormGroup, FormControl, Validators  from '@angular/forms';
import 'rxjs/Rx';

declare var jQuery: any;

@Component(
    selector: 'my-contact',
    templateUrl: 'app/modules/footer/contact/contact.html'
)
export class ContactComponent 

    private contactForm: FormGroup;
    private invalidEmail: boolean;
    private invalidSubject: boolean;
    private invalidMessage: boolean;

    constructor(private apiService: ApiService, private router: Router, private route: ActivatedRoute) 
        this.contactForm = new FormGroup(
            emailControl: new FormControl('', <any>Validators.required),
            subjectControl: new FormControl('', <any>Validators.required),
            messageControl: new FormControl('', <any>Validators.required)
        );
    

    submit() 

        if (this.contactForm.valid) 
            this.apiService.sendMessage(this.contactForm.controls['emailControl'].value, this.contactForm.controls['subjectControl'].value, this.contactForm.controls['messageControl'].value);
        

        if (!this.contactForm.controls['emailControl'].valid) 
            this.invalidEmail = true;
        
        if (!this.contactForm.controls['subjectControl'].valid) 
            this.invalidSubject = true;
        
        if (!this.contactForm.controls['messageControl'].valid) 
            this.invalidMessage = true;
        

    

    ngOnInit() 
        this.invalidEmail = false;
        this.invalidSubject = false;
        this.invalidMessage = false;
    


contact.html:

<modal-header class="c-no-border" [show-close]="true">
  <h4 class="modal-title text-uppercase">Send us a message</h4>
</modal-header>

<form novalidate #contactForm [formGroup]="contactForm" (ngSubmit)="submit()">
  <div class="modal-body">
    <div class="form-group">
      <label for="email" class="control-label">Email</label>
      <input name="email" formControlName="emailControl" placeholder="" type="text" class="c-square form-control c-margin-b-20" id="email">
      <div class="c-font-red-1" *ngIf="invalidEmail" style="position: absolute;">*Required</div>
      <label for="subject" class="control-label">Subject</label>
      <input name="subject" formControlName="subjectControl" placeholder="" type="text" class="c-square form-control c-margin-b-20" id="subject">
      <div class="c-font-red-1" *ngIf="invalidSubject" style="position: absolute;">*Required</div>
      <textarea formControlName="messageControl" style="resize: vertical;" class="c-square form-control c-margin-b-20" id="content" (keyup.enter)="submit()"></textarea>
      <div class="c-font-red-1" *ngIf="invalidMessage" style="position: absolute;">*Required</div>
    </div>
  </div>
  <modal-footer class="c-no-padding">
    <button type="button" class="btn c-btn-square c-btn-bold c-btn-uppercase pull-right">Cancel</button>
    <button type="submit" class="btn c-theme-btn c-btn-square c-btn-bold c-btn-uppercase pull-right" style="margin-right: 10px;">Send</button>
  </modal-footer>
</form>

app.module.ts:

import  NgModule, enableProdMode       from '@angular/core';
import  BrowserModule  from '@angular/platform-browser';
import  AppComponent  from './app.component';
import  FormsModule, ReactiveFormsModule  from '@angular/forms';
import  Ng2Bs3ModalModule  from 'ng2-bs3-modal/ng2-bs3-modal';
import  QueuesModule      from './modules/queues/queues.module';
import  OrderModule      from './modules/order/order.module';
import  AccountModule  from './modules/account/account.module';
import  AdminModule  from './modules/admin/admin.module';
import  routing  from './app.routing';
import  GridModule  from '@progress/kendo-angular-grid';
import  SplashComponent  from './modules/splash/splash.component';
import  ContactComponent  from './modules/footer/contact/contact.component';

import  SharedModule  from './shared/shared.module';
import  EmailValidator  from './shared/utilities/custom-validators'

import  CookieService  from 'angular2-cookie/services/cookies.service';
import  HttpModule, Response  from '@angular/http';
import  StringService  from './services/string.service';
import  ApiService  from './services/api.service';
import  UserService  from './services/user.service';
import  OrderService  from './services/order.service';
import  OrderGuard  from './services/order-guard.service';
import  FooterComponent  from './modules/footer/footer.component';
import  ErrorComponent  from './modules/error/error.component';
import  CustomFormsModule  from "ng2-validation";

@NgModule(
    imports: [
        BrowserModule,
        FormsModule,
        ReactiveFormsModule,
        HttpModule,
        QueuesModule,
        OrderModule,
        AccountModule,
        AdminModule,
        routing,
        GridModule,
        SharedModule,
        Ng2Bs3ModalModule,
        CustomFormsModule
    ],
    declarations: [
        AppComponent,
        SplashComponent,
        FooterComponent,
        ErrorComponent,
        ContactComponent
    ],
    providers: [
        StringService,
        ApiService,
        UserService,
        CookieService,
        OrderService,
        OrderGuard
    ],
    bootstrap: [AppComponent],
    exports: [
    ]
)

export class AppModule 

【问题讨论】:

绑定模板变量#contactForm 似乎会导致名称冲突并炸毁模板处理器。此外,如果您正在编写模型驱动的表单,建议仅导入 ReactiveFormsModule 以强制仅编写反应式表单。当您没有模板变量绑定是问题的双重导入时,这一点变得更加明显。 非常感谢您修复它! 是的,我知道 FormsModule 似乎是多余的,但我把它放在那里是为了很好的衡量标准。我想现在似乎有冲突,我不会同时使用两者。 【参考方案1】:

绑定模板变量#contactForm 似乎会导致名称冲突并破坏模板处理器,因为它试图将附加的模板变量转换为后端的NgForm。我在任何地方都看到使用模型驱动的表单,表单上没有模板变量绑定,而在模板驱动的表单中使用了#tv="ngForm"。混合使用这两种形式的方法似乎有遗漏,导致错误。

只需将其删除即可解决问题。

【讨论】:

【参考方案2】:

如果您错误地将 formGroup="..." 而不是 [formGroup]="..." 添加到模板中,您也会收到此错误消息。

【讨论】:

【参考方案3】:

已经有一段时间了,但对我来说,问题是将 formGroup 传递给模板而不是直接引用它。

例如这不起作用

<ng-template #selectField
             let-field
             let-group
             let-frmName="frmName">
    <ng-container [formGroup]="group">
        <mat-form-field fxFlex="32"
                        floatLabel="always">
            <mat-label>field.label</mat-label>
            <mat-select [formControlName]="frmName"
                        [required]="field.required">
                <mat-option *ngFor="let option of field.options"
                            [value]="option.value">
                    option.description
                </mat-option>
            </mat-select>
        </mat-form-field>
    </ng-container>
</ng-template>

如果我直接使用我的 formGroup 实例,它就可以正常工作。

希望这会有所帮助。

【讨论】:

【参考方案4】:

我有一个动态表格。由于我没有在 ngOnInit() 中初始化它,所以我遇到了上述错误

解决方案:

checkInForm: FormGroup;

ngOnInit()
    this.checkInForm = this.formBuilder.group();

【讨论】:

谢谢。这就是我的问题。【参考方案5】:

当您在不是表单控件的自定义组件上使用输入名称 formControlformGroup 时,可能会发生这种情况。

更改您的自定义组件以接受不同的输入名称:

改变这个

@Input()
formGroup: string
// ^ Causes issues

到这里

@Input()
group: string

【讨论】:

以上是关于TypeError:this.form._updateTreeValidity 不是函数的主要内容,如果未能解决你的问题,请参考以下文章

form submit时将__VIEWSTATE和__VIEWSTATEGENERATOR一起post到另外的页面,出现验证视图状态 MAC 失败。

TypeError 'x' 对象没有属性 '__getitem__'

TypeError:'function'对象没有属性'__getitem__' [关闭]

TypeError:“__ensemble__”对象不可调用

TypeError: __init__() 得到了一个意外的关键字参数“评分”

TypeError: __init__() 接受 2 个位置参数,但给出了 4 个