【问题标题】:Push only checked and not duplicated checkbox values to an array in Angular?仅将选中而不是重复的复选框值推送到Angular中的数组?
【发布时间】:2022-02-18 15:58:14
【问题描述】:

我有三个复选框,我想创建一个数组,该数组应该包含选中复选框值的值,并且应该避免推送重复值

这是我尝试过的,但无论是否选中,值都在推动。

谁能告诉我这里有什么问题?

.ts

public dataSource: any[] = [];

compsForm: FormGroup = new FormGroup({

  dataSource: new FormControl('', Validators.required),
  name: new FormControl('',Validators.required),
});
    dataSourceChange(event:any){
    
        var name = event.target.name;
        var isChecked = event.target.checked;
        const index = this.dataSource.findIndex((el) => el.id === name);
    
        if (index > -1) {
          this.dataSource[index].isChecked = isChecked;
        } else {
          this.dataSource.push(name);
        }
        this.dataSource = [...this.dataSource];
        console.log(this.dataSource);
      }

.html

<form [formGroup]="compsForm">
     <input type="checkbox" name="om" (change)="dataSourceChange($event)" formControlName = "dataSource"> <span> OM</span>
     <input type="checkbox" name="fe" (change)="dataSourceChange($event)" formControlName = "dataSource"> <span> FE</span>
     <input type="checkbox" name="be" (change)="dataSourceChange($event)" formControlName = "dataSource"> <span> BE </span>
</form>

【问题讨论】:

  • 发布您的其余工作(整个组件)。
  • 我现在添加了其余的东西 :)

标签: arrays angular typescript checkbox event-handling


【解决方案1】:

需要考虑的一些事项:

ts 中的 formGroup 应该与 html 中表单的“形状”相匹配。 如果 html 表单有 3 个输入,那么 formGroup 也应该如此。 每个输入的 html 应该有不同的名称。

你只是在你的数组中推送元素而不是在取消选中时删除它们,所以数组会越来越大。

当您担心重复条目时,最好使用“集合”,并在完成所有工作后将集合转换为数组。

查看这个 SO 答案:HashSet Explanation

.html

    <form [formGroup]="compsForm">
  <input
    type="checkbox"
    name="om"
    (change)="dataSourceChange($event)"
    formControlName="dataSource1"
  />
  <span> OM</span>
  <input
    type="checkbox"
    name="fe"
    (change)="dataSourceChange($event)"
    formControlName="dataSource2"
  />
  <span> FE</span>
  <input
    type="checkbox"
    name="be"
    (change)="dataSourceChange($event)"
    formControlName="dataSource3"
  />
  <span> BE </span>
</form>

.ts

     // private _dataSource: any[] = [];
  private _dataSet: Set<string> = new Set<string>();
  private _dataArray = [];

  compsForm: FormGroup = new FormGroup({
    dataSource1: new FormControl(''),
    dataSource2: new FormControl(''),
    dataSource3: new FormControl(''),
  });

  dataSourceChange(event: any) {
    console.log(event.target.name);

    const name = event.target.name;
    const isChecked = event.target.checked;

    if (isChecked) this._dataSet.add(name);
    else this._dataSet.delete(name);

    this._dataArray = Array.from(this._dataSet);
    console.log(this._dataArray);
  }

【讨论】:

    【解决方案2】:

    这个想法来自this SO(简单的部分,例如带有变量)。您只需通过 formControl 更改变量“answer”。

    <div *ngFor="let option of options">
      <input
        #check
        type="checkbox"
        [checked]="compsForm.get('dataSource').value &&
                   compsForm.get('dataSource').value.indexOf(option) >= 0"
        (change)="onChange(option, check.checked)"
      />
    
      {{ option }}
    </div>
    
      options=["check 1","check 2","check3"]
      compsForm: FormGroup = new FormGroup({
    
        dataSource: new FormControl('', Validators.required),
        name: new FormControl('',Validators.required),
      });
      onChange(option:string,checked:boolean)
      {
         let answer=this.compsForm.get('dataSource').value || [];
         if (checked && answer.indexOf(option)<0)
         {
             answer=[...answer,option]
             .sort((a,b)=>this.options.indexOf(a)>this.options.indexOf(b)?1:-1)
             //we can also not sort the array
             //answer=[...answer,option]
         }
    
        if (!checked)
              answer=answer.filter(x=>x!=option)
    
        this.compsForm.get('dataSource').setValue(answer.length?answer:null)
      }
    

    stackblitz

    注意:如果你只想要代码,你可以使用 getter

    get dataSourceValue(){
       return this.compsForm.get('dataSource').value
    }
    

    更新选项作为带有值和标签的数组

    如果我们有一些喜欢

    options2 = [
        { value: 'check1', label: 'Check 1' },
        { value: 'check2', label: 'Check 2' },
        { value: 'check3', label: 'Check 3' },
      ];
    

    我们需要修改一些代码

    <div *ngFor="let option of options2">
      <input
        #check
        type="checkbox"
        [checked]="compsForm2.get('dataSource').value &&
                   compsForm2.get('dataSource').value.indexOf(option.value) >= 0"
        (change)="onChange2(option.value, check.checked)"
      />
      {{ option.label }}
    </div>
    

    看看我们如何传递给函数option.value并询问.value.indexOf(option.value)

    我们的功能变化变成了

      onChange2(option: string, checked: boolean) {
        let answer = this.compsForm2.get('dataSource').value || [];
        if (checked && answer.indexOf(option) < 0) {
    
          //we use "optionsValue" for easy sort
          const optionsValue = this.options2.map((x) => x.value);
    
          answer = [...answer, option].sort((a, b) =>
            optionsValue.indexOf(a) > optionsValue.indexOf(b) ? 1 : -1
          );
          //we can also not sort the array
          //answer=[...answer,option]
        }
    
        if (!checked) answer = answer.filter((x) => x != option);
    
        this.compsForm2.get('dataSource').setValue(answer.length ? answer : null);
        this.compsForm2.get('dataSource').markAsTouched();
      }
    

    【讨论】:

      猜你喜欢
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 2018-07-26
      相关资源
      最近更新 更多