将复选框控件与文本框控件相关联的最佳方法

时间:2017-07-23 21:47:13

标签: angular angular-reactive-forms

我一直在尝试许多不同的方法一周都失败了,我需要能够将复选框控件与答案相关联。

差不多,如果勾选了复选框,那么用户必须回答问题并且必须验证minlength 4.

该复选框将包含问题和答案。

因此,如果用户选择该问题,他/她必须提供答案。

问题从服务器呈现在诸如;

之类的对象中
 displayArray;
 getchar;

如果需要,我可以发布我的代码,但它很长很复杂。

enter image description here

1 个答案:

答案 0 :(得分:2)

如果您创建Reactive Form,则可以动态更改验证

<强>组件

this.questionForm = fb.group({
  questions: fb.array(this.questions.map(this.createQuestionControl(fb)))
});

createQuestionControl(fb: FormBuilder) {
  return (question, index) => {
    const checkbox = question.selected
    const answerbox = question.selected ? ['', [Validators.required, Validators.minLength(4)]] : ''
    return fb.group({question: checkbox, answer: answerbox, questionNumber: index + 1});
  }
}

changeValidator(selected, index) {
  const answerbox = this.questionForm.get('questions.' + index).get('answer')

  const validators = selected ? [Validators.required, Validators.minLength(4)] : null
  answerbox.setValidators(validators);
  answerbox.updateValueAndValidity();
}

createQuestionControl()方法会将每个问题都更改为控件,如下所示,表单构建器可以转换为带有问题和答案的组

{ question: true, answer: ['', [Validators.required, Validators.minLength(4)]], index: 4 }

如果问题发生了变化,changeValidator()方法会在答案上添加或删除验证器(注意:不要忘记updateValueAndValidity

<强>模板

<form [formGroup]="questionForm" (ngSubmit)="submit(questionForm)">

  <div formArrayName="questions">
    <div *ngFor="let question of questionForm.get('questions').controls | orderBySelected; let i = index;" [formGroupName]="i">
      <!--{{questionForm.get('questions.' + i + '.questionNumber').value}}-->
      {{questions[questionForm.get('questions.' + i + '.questionNumber').value - 1]['EN']}}
      <input type="checkbox" formControlName="question" (ngModelChange)="changeValidator($event, i)"/>
      <input type="text" formControlName="answer" />
      <em *ngIf="questionForm.get('questions.' + i + '.answer').invalid">Minimum length 4</em>
    </div>
  </div>

  <button type="submit" [disabled]="questionForm.invalid">Submit</button>

</form>

在评论中作出澄清后:

  

在给定时间可以检查最多5个

我更新了数组,使交叉字段验证不超过3(更容易测试,你可以将其更改为5)

export function max3Selected(formArray) {

  let totalSelected = formArray.controls.reduce((selectedControls, control) => 
  {
    if (control.get('question').value) {
      selectedControls++
    }
    return selectedControls;
  }, 0)

  return totalSelected > 3 ? { moreThanThreeSelected: true } : null;
}

您可以更改fb.array以包含验证程序功能

fb.array(this.questions.map(this.createQuestionControl(fb)), max3Selected)

结果截图

enter image description here

Live plunker example