简体   繁体   English

Angular 反应式 forms 复选框验证

[英]Angular reactive forms checkbox validations

I'm trying to make a required validation to my checkboxes.我正在尝试对我的复选框进行必要的验证。

My TS file:我的 TS 文件:

public colors: Array<any> = [
     { description: 'White', value: 'White' },
     { description: 'Black', value: 'Black' },
     { description: 'Blue', value: 'Blue' },
     { description: 'Green', value: 'Green' },
     { description: 'Yellow', value: 'Yellow' },
     { description: 'Red', value: 'Red' },
];
    
constructor(
    private formBuilder: FormBuilder,
    private heroService: HeroService,
    private toastr: ToastrService
  ) {
  this.fromInit();
}

ngOnInit(): void {}

fromInit() {
  this.heroCreateForm = this.formBuilder.group({
    suitColors: new FormArray([], [Validators.required]),
  });
}

onCheckChange(event) {
  const formArray: FormArray = this.heroCreateForm.get(
    'suitColors'
  ) as FormArray;

  if (event.target.checked) {
    formArray.push(new FormControl(event.target.value));
  } else {
    let i: number = 0;

    formArray.controls.forEach((ctrl: FormControl) => {
      if (ctrl.value == event.target.value) {
        formArray.removeAt(i);
        return;
      }
      i++;
    });
  }
}


invalidSuitColorsMessage() {
   // this function doesn't work
   if (this.suitColors.errors?.required)
      return "You must choose the hero's suit colors";
}

My HTML file:我的 HTML 文件:

<div class="main-content">
  <form [formGroup]="heroCreateForm" (ngSubmit)="createHero()">
    <div class="container">

      <div class="input-container-suitColors-input">
        <label><b>Suit colors: </b></label>
        <ng-container *ngFor="let color of colors; let i=index">
          <div class="radio-contatiner">
            <input type="checkbox"
                   [value]="color.value"
                   (change)="onCheckChange($event)">
            {{color.description}}
          </div>
        </ng-container>
      </div>

      <div class="invalid-input-message"
           *ngIf="suitColors.touched && suitColors.invalid">{{invalidSuitColorsMessage()}}</div>

// here is the issue. I'm getting here an error

      <hr>

      <button type="submit"
              class="registerbtn"
              [disabled]="heroCreateForm.invalid">Register</button>
    </div>
  </form>
</div>

Error错误

Cannot read properties of undefined (reading 'touched')无法读取未定义的属性(读取“触及”)

I do understand why it does work.我明白为什么它会起作用。 I search online and didn't find any solution to my issue.我在网上搜索并没有找到任何解决我的问题的方法。

I'm trying to show a message if the required error happens on those checkboxes如果这些复选框上发生所需的错误,我正在尝试显示一条消息

Does anyone can take a look and explain to me why does it happen and how should I fix it?有谁可以看看并向我解释为什么会发生以及我应该如何解决它?

The error said the variable touched can't be found because the object that should contains it is not defined.错误说找不到变量touched ,因为没有定义应该包含它的object。 In other language it's also called as null .在其他语言中,它也称为null More explaination about undefined关于未定义的更多解释

In your case, suitColors is not defined.在您的情况下, suitColors So there is multiple ways:所以有多种方式:

  1. You can define it.你可以定义它。 For example, in the constructor like that:例如,在这样的构造函数中:
constructor(private formBuilder: FormBuilder, private heroService: HeroService,
   private toastr: ToastrService, public suitColors: MyObject) {
   this.fromInit();
}

Or as public variable like that:或者像这样的公共变量:

public suitColors: MyObject;

constructor(private formBuilder: FormBuilder, private heroService: HeroService, private toastr: ToastrService) {
   this.suitColors = new MyObject();
   this.fromInit();
}
  1. Check in the *ngIf before use it.在使用前检查*ngIf With this way, you should add a check for ALL object.通过这种方式,您应该添加对 ALL object 的检查。 Also, this will work everytime, even if you define object after ngInit.此外,即使您在 ngInit 之后定义 object,这也将始终有效。
<div class="invalid-input-message"
           *ngIf="suitColors != null && suitColors.touched && suitColors.invalid"> 
    {{invalidSuitColorsMessage()}}
</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM