Javascript 角度反应窗体-验证错误-无法读取未定义或null的属性

Javascript 角度反应窗体-验证错误-无法读取未定义或null的属性,javascript,angular,angular-reactive-forms,Javascript,Angular,Angular Reactive Forms,我花了很长时间去理解一些应该很容易的事情。表单验证。我第一次使用反应形式。我正在使用表单生成器。我有一套嵌套的控件。通常,我假设您创建一组具有验证的控件,然后检查模板中的控件。我可以提交表单,但在尝试创建验证消息时不断出现错误 ------ TEMPLATE ------- <div class="container"> <div class="row"> <div class="col-sm"> <!-- Begin ca

我花了很长时间去理解一些应该很容易的事情。表单验证。我第一次使用反应形式。我正在使用表单生成器。我有一套嵌套的控件。通常,我假设您创建一组具有验证的控件,然后检查模板中的控件。我可以提交表单,但在尝试创建验证消息时不断出现错误


------ TEMPLATE -------

<div class="container">
  <div class="row">
    <div class="col-sm">

      <!-- Begin card -->
      <div class="card border">
        <div class="card-header bg-light text-primary">
          <h3>My Account</h3>
        </div>
        <div class="card-body border border-light">
          <!-- CHANGE PASSWORD BUTTON -->
          <div class="row">
            <div class="col-sm">
              <button class="btn btn-success" (click)="goToChangePassword()">Change Password</button>
            </div>
          </div>
          <!-- Begin Form -->
          <form *ngIf="user; else loading" [formGroup]="accountForm" (ngSubmit)="updateUser()">
            <hr>
            <!-- Phone -->
            <fieldset formGroupName="phone">
              <div class="form-row">
                <div class="form-group col-sm">
                  <label>Home Phone</label>
                  <input type="number" class="form-control" formControlName="home">
                  <div *ngIf="isSubmitted && fControls.home.errors" class="invalid-feedback">
                    <div *ngIf="fControls.home.errors.minlength">10 characters min</div>
                  </div>
                </div>
                <div class="form-group col-sm">
                  <label>Mobile Phone</label>
                  <input type="number" class="form-control" formControlName="mobile">
                  <div *ngIf="isSubmitted && fControls.mobile.errors" class="invalid-feedback">
                    <div *ngIf="fControls.mobile.errors.minlength">10 characters min</div>
                  </div>
                </div>
                <div class="form-group col-sm">
                  <label>Extension</label>
                  <input type="number" class="form-control" formControlName="extension">
                  <div *ngIf="isSubmitted && fControls.extension.errors" class="invalid-feedback">
                    <div *ngIf="fControls.extension.errors.maxlength">5 chartacters max</div>
                  </div>
                </div>
              </div>
            </fieldset>

            <!-- BIRTHDAY -->
            <fieldset formGroupName="birthday">
              <div class="form-row">
                <div class="form-group col-sm-3">
                  <label>Birthday Month</label>
                  <input type="number" class="form-control" formControlName="month">
                </div>
                <div class="form-group col-sm-3">
                  <label>Birthday Day</label>
                  <input type="number" class="form-control" formControlName="day">
                </div>
              </div>
            </fieldset>
            <hr />

            <!-- BUTTONS -->
            <div class=" form-row">
              <button type="submit" class="btn btn-success mr-3" [disabled]="!accountForm.valid">Update</button>
              <button class="btn btn-danger" (click)="cancel()">Cancel</button>
            </div>


            <!-- End form -->
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- LOADING TEMPLATE -->
<ng-template #loading>
  Loading User...
</ng-template>



------ TS --------

import { Component, OnInit } from '@angular/core';
import { UserService } from 'src/app/services/user.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { AppToastService } from 'src/app/services/toastr.service';

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html',
  styleUrls: ['./account.component.css']
})
export class AccountComponent implements OnInit {
  user;
  userId;
  accountForm: FormGroup;
  isSubmitted = false;

  constructor(
    private _userService: UserService,
    private _router: Router,
    private _toast: AppToastService,
    private fb: FormBuilder
  ) {}

  ngOnInit() {
    // Initiate the form
    this.accountForm = this.fb.group({
      phone: this.fb.group({
        home: [' ', Validators.minLength(10)],
        mobile: [' ', Validators.minLength(10)],
        extension: [' ', Validators.maxLength(5)]
      }),
      birthday: this.fb.group({
        month: '',
        day: ''
      })
    });

    // Get userId from localstorage, then fetch the details
    this.userId = this._userService.getUserIdFromLocalStorage();

    // Get user from userId
    this._userService.getUserAccountInfo(this.userId).subscribe(
      response => {
        this.user = response['user'];
        this.accountForm.patchValue(response['user']);
      },
      error => console.log(error['message'])
    );
  }

  // Access form controls
  get fControls() {
    return this.accountForm.controls;
  }

  updateUser() {
    // Check for form validity
    this.isSubmitted = true;
    if (this.accountForm.invalid) {
      return;
    }

    let updatedUser = this.accountForm.value;
    updatedUser.id = this.userId;

    console.log(updatedUser);

  }


------模板-------
我的帐户
修改密码

家庭电话 最少10个字符 手机 最少10个字符 延伸 最多5个chartacters 生日月 生日
更新 取消 正在加载用户。。。 ------TS-------- 从“@angular/core”导入{Component,OnInit}; 从'src/app/services/user.service'导入{UserService}; 从“@angular/forms”导入{FormBuilder、FormGroup、Validators}; 从'@angular/Router'导入{Router}; 从'src/app/services/toastr.service'导入{AppToastService}; @组成部分({ 选择器:“应用程序帐户”, templateUrl:“./account.component.html”, 样式URL:['./account.component.css'] }) 导出类AccountComponent实现OnInit{ 用户; 用户标识; 账户形式:FormGroup; isSubmitted=false; 建造师( private\u userService:userService, 专用路由器:路由器, 私人土司:AppToastService, 私人fb:FormBuilder ) {} 恩戈尼尼特(){ //发起表格 this.accountForm=this.fb.group({ 电话:this.fb.group({ 首页:['',验证器。最小长度(10)], 手机:['',验证器.最小长度(10)], 扩展名:['',验证器。maxLength(5)] }), 生日:this.fb.group({ 月份:'', 日期:'' }) }); //从localstorage获取用户ID,然后获取详细信息 this.userId=this.\u userService.getUserIdFromLocalStorage(); //从userId获取用户 此.\u userService.getUserAccountInfo(this.userId).订阅( 响应=>{ this.user=响应['user']; this.accountForm.patchValue(响应['user']); }, error=>console.log(错误['message']) ); } //访问表单控件 获取fControls(){ 返回this.accountForm.controls; } updateUser(){ //检查表格的有效性 this.issubmitt=true; if(此.accountForm.invalid){ 返回; } 让updateUser=this.accountForm.value; updateuser.id=this.userId; console.log(updateuser); }
使用安全导航操作符
。它检查变量是否为
未定义
,以便我们的模板不会尝试选择错误的属性

在您的情况下,在您试图使用
运算符访问对象属性的模板中使用它,例如:
*ngIf=“Isubmitted&&fControls?.home?.errors”


注意:您不应该将其用于模型绑定
[(ngModel)]=“employee?.name”
错误

使用安全导航操作符
。它检查变量是否为
未定义
,以便我们的模板不会尝试选择错误的属性

在您的情况下,在您试图使用
运算符访问对象属性的模板中使用它,例如:
*ngIf=“Isubmitted&&fControls?.home?.errors”


注意:您不应该在模型绑定中使用相同的
[(ngModel)]=“employee?”name“
错误

在任何地方使用安全导航操作符(模型绑定除外),例如
*ngIf=“isSubmitted&&fControls?.home?.errors”
在任何地方使用安全导航操作符(模型绑定除外)例如
*ngIf=“isSubmitted&&fControls?.home?.errors”
谢谢Joel。我在模板驱动表单中使用了这些运算符,但没有在反应表单中使用。现在错误消失了。奇怪的是,我的验证插件不起作用。我对每个数字都有一个minlength属性,如果我使用,请尝试提交5个数字(少于10个)然后它正确地提交并且报告没有问题。想知道为什么会这样。谢谢Joel。我在模板驱动的表单中使用了这些运算符,但没有在反应表单中使用。现在错误消失了。奇怪的是,我的验证ins不起作用。我对每个数字都有minlength属性,如果我带来,请尝试提交5个数字(少于10个)然后它正确地提交并且报告没有问题。想知道为什么会这样。