【问题标题】:Best way to associate checkbox control with textbox control将复选框控件与文本框控件关联的最佳方法
【发布时间】:2017-12-29 10:12:36
【问题描述】:

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

差不多,如果复选框被选中,那么用户必须回答这个问题并且它必须有一个最小长度 4 的验证。

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

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

问题从服务器呈现在一个对象中,例如:

 { 
                question_id: "1",
                selected: true,
                EN: "Question 1 - EN",
                FR: "Question 1 -FR",

            },
            { 
                question_id: "2",
                selected: false,
                EN: "Question 2 - EN",
                FR: "Question 2 -FR"
            }

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

【问题讨论】:

  • 您能传达您遇到的问题吗? “复选框将包含一个问题和答案。” - 我认为您的意思是某种组件将包含一个复选框,如果选中它将控制输入的显示,您可以使用 *ngIf 控制该输入。 ReactiveFormControl 推荐用于验证功能angular.io/guide/reactive-formsangular.io/api/forms/Validators
  • 嘿,我已经添加了我正在做的事情的图像。本质上,当我从服务器检索问题时,我需要: 1. 显示问题以及复选框并回答输入控件 2. 具有最小长度(4)的内联验证 3. 有 20 个问题,您必须选择 5。我遇到的问题是,当我选择 5 时,仍然会为未选择的那些触发验证。我尝试通过 .setValidators 和 .clearValidators 手动添加验证器。
  • 当我检查5个问题并回答它们并转到下一页时,它们应该作为对象存储。当我从下一页回击时,应使用复选框显示已回答的相同问题。我能够做到这一点,但填充 answercontrol(文本输入)的答案不会触发最小长度 4 的验证,我认为未选中的复选框也会触发验证,因此不允许我再次提交。
  • 也许看看这里..明天会跟进..stackoverflow.com/a/33377290/495157

标签: angular angular-reactive-forms


【解决方案1】:

如果您创建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>

根据 cmets 的说明:

在给定时间最多可以检查 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)

结果截图

Live plunker example

【讨论】:

  • 在给定时间最多可以检查 5 个,我正在使用您的解决方案 -- 但它允许我检查超过 5 个。
  • 我还注意到,当你选择一个复选框时——如果你 console.log(question) 属性总是被选中:true,即使你取消选中——但复选框未被选中,选中的属性是仍然正确;
  • 我问是因为无论是否检查问题都会显示我的答案输入。使用动画。 这不起作用但是,question.selected 在提交之前始终为真。
  • 我相信您选择最多 5 个的 plunkr 示例,只允许我选择 1 并提交 -- 它可能会被反转?
猜你喜欢
  • 1970-01-01
  • 2018-07-25
  • 2020-10-03
  • 1970-01-01
  • 2011-07-20
  • 2019-04-22
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多