【问题标题】:get multiple checkbox value as an array in angular获取多个复选框值作为角度数组
【发布时间】:2020-12-27 01:50:51
【问题描述】:

我正在尝试从此处的多个复选框中获取值https://stackblitz.com/edit/angular-ivy-uahtjx 我尝试了这种方法,但对我来说没有https://stackblitz.com/edit/quiz-answer-value 我认为这是因为 JSON 模式不同,第一个是数组,第二个是是对象。

我这样设置我的html

<div *ngFor="let option of form.options">
  <label><input (change)="onChange(i,j, form.code,check.checked)" #check 
  [value]="answers[i].value.forms[j].answer.toString().indexOf(form.code)>=0" formControlName="answer" type="checkbox">{{option}}</label>
</div>

对于我这样的更改功能

onChange(indexi: number, indexj: number, code: string, isChecked: boolean) {
  const control = this.answerArray.at(indexi).get("forms")['controls'][indexj].get('answer');
  console.log(control);
}

有人可以帮我吗?

【问题讨论】:

    标签: json angular angular-reactive-forms angular-forms


    【解决方案1】:

    您的代码中有几个错误。

    您指出的最后一个堆栈闪电战(来自this SO)是一种“富有想象力”的方式来管理一系列复选框以提供存储字符串数组的 formControl。这个想法是输入有[checked](change),但是NOT formControlName(这是因为一开始复选框变成了“已选中”)。 formControl 在表单中没有输入。是的,formControl 存在,但没有输入。

    复选框的[checked] 是一个函数,指示“选项”是否包含在控件的值中(使用 indexOf)

    (change) 具有参数、索引 - 用于本地化 formControl-、“选项”的值以及是否选中。

    一个more simple stackblitz 来展示这个概念:

    <!--see that "answer" has no input, it's only a variable in .ts-->
    <div *ngFor="let option of options">
    <input #check type="checkbox"
      [checked]="answer.indexOf(option)>=0"
      (change)="onChange(option,check.checked)"
    >
    {{option}}
    </div>
    
      answer=["check 2"]
      options=["check 1","check 2","check3"]
      onChange(option:string,checked:boolean)
      {
         if (checked && this.answer.indexOf(option)<0)
             this.answer=[...this.answer,option]
             .sort((a,b)=>this.options.indexOf(a)>this.options.indexOf(b)?1:-1)
        if (!checked)
              this.answer=this.answer.filter(x=>x!=option)
      }
    

    好吧,在你的代码中

    1.-改变表单(请看代码中的cmets)

        <div *ngIf="form.type == 'checkbox'">
            <p>{{form.title}}</p>
            <div *ngFor="let option of form.options">
               <!--in your code WRONG (change)="onChange(i,j, form.code,check.checked)" -->
               <!-- see that we need send the "option", not the form.code-->
                <label><input #check (change)="onChange(i,j, option,check.checked)"
               <!--use checked, not value, and remove the "toString"-->
                 [checked]="answers[i].value.forms[j].answer.indexOf(option)>=0"
                  <!--see that we has no formControlName="answer" -->
                  type="checkbox">{{option}}</label>
            </div>
        </div>
    

    函数onChange,它只是如果checked=true 添加“代码”,如果checked=false 删除“代码”。好吧,有一个困难是“排序”响应。为了对响应进行排序,我们比较“选项”中的 indexOf 值

    我使用辅助变量“options”来获取“options”

    2.-改变你的函数 onChange by

      onChange(indexi: number, indexj: number, code: string, isChecked: boolean) {
        const control = this.answerArray.at(indexi).get("forms")["controls"][indexj]
          .controls.answer;
        
        const options=this.listFormField[indexi].sectionItems[indexj].options
        //options will be, eg. ["check 1","check 2","check 3"]
        if (isChecked && control.value.indexOf(code) < 0)
          control.setValue(
            [...control.value, code].sort((a: string, b: string) =>
              options.indexOf(a) >options.indexOf(b)
                ? 1
                : -1
            )
          );
    
        if (!isChecked && control.value.indexOf(code) >= 0)
          control.setValue(control.value.filter(x => x != code));
      }
    

    注意:您需要修改代码,实际上,当您创建表单时,您所有的“答案”都是数组(只需将它们是复选框的“答案”数组)

    已更新为避免在 answer 为 null 时出现错误,我们可以或避免在创建表单时,或者另一种选择,将代码更改为选中为

    [checked]="(answers[i].value.forms[j].answer || []).indexOf(option)>=0"
    

    路径值我们可以,如果只是一个元素,例如

    const i=0
    const j=1
    this.response.get('answers.'+i+'.forms.'+j+'.answer')
         .patchValue(["check 1","check 2"])
    

    是的,要获得“答案”,我们可以通过索引使用“get”。也许这很容易理解,因为当我们使用 formGroup 的 formArray 时,我们会写 [formGroupName]="i"。如果我们想在 FormGroup 上创建 pathValue,我们需要考虑,如果我们在数组上创建 pathValue,pathValue 不会将元素添加到 formArray,因此如果我们发送更多元素,则不会添加它。此外,如果我们发送更少的元素,pathValue,删除元素

    考虑到这一点,我们也可以制作,例如

    this.response.get('answers.'+i+'.forms')
         .patchValue(
            [
              {answer:"radio 2"},
              {answer:["check 1","check 2"]},
              {answer:"text input"},
              {answer:"text area"},
              {answer:["check 6"]},
             ]
            )  
    

    【讨论】:

    • 我实际上是在 10 小时前工作的,我根据我的 stackblitz 代码找到了解决方案,只是在玩,我得到了我想要的结果,它与你的最终代码相似,但我没有添加[checked]="answer.indexOf(option)&gt;=0" 可以吗?因为它似乎在我的应用程序上没有它工作
    • control.value.indexOf 对我来说它给了我一个错误说它不是一个函数,所以我把它改成了这个control.value.toString().indexOf
    • 如果“anwser”为空,则会引发错误。正确转换为字符串或使用 [checked]="(answer || []).indexOf(option)&gt;=0" -the "answer || []) main 如果答案为 null 或未定义或 "",则取空数组的值
    • 我明白这就是为什么你不需要 toString
    • 答案已更新! :)。顺便说一句,在您的代码中,创建表单后,您不需要使用两个循环来路径、值。看你在创建表单时给出的值
    猜你喜欢
    • 2020-03-02
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多