【问题标题】:Angular how to get the multiple checkbox values?Angular如何获取多个复选框值?
【发布时间】:2017-09-11 09:50:06
【问题描述】:

我在 Angular 中使用一个复选框来选择多个元素,并且我正在尝试获取该复选框的值以进行提交。

相反,我将这些值作为true-s 的数组获取。 这就是我尝试过的:

export class CreateSessionComponent implements OnInit {
  form : FormGroup ;

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.form = this.formBuilder.group({
      userdata :  new FormArray([
        new FormControl('', Validators.required)
      ])
    })
  }
}

userdata 是从数据库填充的动态数组。

<div formArrayName="useremail; let k = index">
  <div *ngFor="let data of userdata">
    <div>
      <input type="checkbox" name="useremail" formControlName ="{{k}}" [value]="data.email">{{data.email}}
    </div>
  </div>
</div> 

【问题讨论】:

  • 可能有多个复选框

标签: angular angular2-forms


【解决方案1】:

由于您要使用多个值,因此您需要使用FormArray,因为FormControl 只能捕获一个值。

从声明一个空的formArray开始:

this.myForm = this.fb.group({
  useremail: this.fb.array([])
});

迭代您的电子邮件,并注意更改事件并将相应的电子邮件和事件传递给方法onChange,在该方法中检查它是否为checked,然后将相应的电子邮件添加到formarray,如果未选中,请删除从表单数组中选择的电子邮件:

<div *ngFor="let data of emails">
  <input type="checkbox" (change)="onChange(data.email, $event.target.checked)"> {{data.email}}<br>
</div>

还有onChange:

onChange(email:string, isChecked: boolean) {
  const emailFormArray = <FormArray>this.myForm.controls.useremail;

  if(isChecked) {
    emailFormArray.push(new FormControl(email));
  } else {
    let index = emailFormArray.controls.findIndex(x => x.value == email)
    emailFormArray.removeAt(index);
  }
}

Demo

【讨论】:

  • 如果有多个值被检查,那么我怎样才能得到上面的多个值得到单个检查值
  • data.email 是一个动态值,我将从包含多个值的数据库中获取该值
  • 这些值是什么?复选框在哪里,它们都是电子邮件复选框吗?您只有一个表单控件,因此您不能捕获多个。您可能不得不使用一些 formarray/nested formgroup,但如果您不显示更多代码,就不可能提供进一步的帮助。
  • 从您在 plunker data = {email:"email value",email:"value2"} 中的回答包含两个值,如果两个值都被选中,那么我如何在表单提交中获取这些值
  • 那么你必须为邮件创建一个formarray而不是formcontrol。
【解决方案2】:

@AJT_82 答案的问题是,如果您想使用 form.reset()form.patchValue() 修改模型,它不会不工作。要解决这些问题,您需要实现ControlValueAccessor 接口。 基本上,您需要创建 2 个组件:保存模型值并实现 ControlValueAccessor 的组组件和复选框组件,即实际的复选框。 我已经写了a blog post 的详细解释,并创建了一个plunker 来演示一些示例。

最终用法:

<checkbox-group [(ngModel)]="selectedItems">
    <checkbox value="item1">Item 1</checkbox>
    <checkbox value="item2">Item 2</checkbox>
    <checkbox value="item3">Item 3</checkbox>
    <checkbox value="item4">Item 4</checkbox>
</checkbox-group>

组组件的实现:

@Component({
selector: 'checkbox-group',
template: `<ng-content></ng-content>`,
providers: [{
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CheckboxGroupComponent),
      multi: true
    }]
 })
export class CheckboxGroupComponent implements ControlValueAccessor {
  private _model: any;

  // here goes implementation of ControlValueAccessor
  ...

  addOrRemove(value: any) {
    if (this.contains(value)) {
        this.remove(value);
    } else {
        this.add(value);
    }
  }

  contains(value: any): boolean {
    if (this._model instanceof Array) {
        return this._model.indexOf(value) > -1;
    } else if (!!this._model) {
        return this._model === value;
    }

    return false;
  }

  // implementation for add and remove
  ...
}

复选框组件:

@Component({
selector: 'checkbox',
template: `
  <div (click)="toggleCheck()">
    <input type="checkbox" [checked]="isChecked()" />
    <ng-content></ng-content>
  </div>`
})
export class CheckboxComponent {
  @Input() value: any;

  constructor(@Host() private checkboxGroup: CheckboxGroupComponent) {
  }

  toggleCheck() {
    this.checkboxGroup.addOrRemove(this.value);
  }

  isChecked() {
    return this.checkboxGroup.contains(this.value);
  }
}

子复选框控件引用了组组件(@Host() 装饰器)。当一个复选框被点击toggleCheck()调用组组件上的addOrRemove()方法并且如果复选框的值已经在模型中,它被移除,否则它被添加到型号。

【讨论】:

  • 虽然乍看之下看起来更复杂,但这是我在该主题上找到的最佳答案,但这些类一旦包含在工具箱中就非常可重用且干净,谢谢。
  • 有一个小问题,复选框的标签不会触发更改事件,只有实际的复选框部分。请参阅此 plunker plnkr.co/edit/BAhzLYo9e4H8PdAt9lGR?p=preview 尝试同时单击复选框方块和标签,两者都会触发复选框,但只有复选框部分会触发更改。
  • @owlyfool 我不明白你指的是什么。当您单击包含复选框和标签的 div 时,将调用 toogleCheck()。所以点击复选框和标签会触发相同的行为。
  • [x]
  • 您需要将 (change)="..." 放在复选框组组件上。它是保存模型值的组件。
【解决方案3】:

您可以获得检查数据的数组:

<input .... (change)="onChange(data)" />
onChange(data){
   data.checked = !data.checked;
}

获取所有检查值

let checkedValues = userdata.filter(x => x.checked).map(x => x.email);

【讨论】:

  • “数据”与“用户数据”有何关系?我也很困惑,因为您只显示一个输入,但数据似乎没有键控,所以如果我有 10 个这样的输入,它们都只会切换一个“数据”变量,不是吗?最后,我不确定我是否理解“x.email”参考。我正在尝试完全按照您的示例的意图进行操作,但对将缺失的部分拼凑起来还不够了解。任何帮助将不胜感激!
【解决方案4】:

对于 Angular 2+,请查看此示例 link

【讨论】:

    【解决方案5】:

    我在加载表单自动选择的输入处执行了此功能:

    [checked]="this.selected?this.selected.type.includes(type) : false"

    完整代码:

    <label *ngFor="let type of this.entityType" class="checkbox-inline c-checkbox">
    <input type="checkbox" [checked]="this.selected? this.selected.type.includes(type) : false" (change)="onChangeEntityType(type, $event.target.checked)"/>
    <span class="fa fa-check"></span>{{type | translate}}</label>
    

    在哪里

    this.selected

    是我的对象和

    this.selected.type.includes(type)

    自动检查复选框是否会被选中。

    【讨论】:

      【解决方案6】:

      我用两种不同的方式解决了 一个带有简单复选框数组的 - mat-checkbox 另一个是 mat-selection-list。

      帖子中的代码要点。 在该值,您可以设置所有类型的组合。 在我的例子中,我使用了 id 和 description 的连接,以便在最后从一个来源初始化表单控件..

      https://medium.com/@2bhere4u/angular-5-material-design-checkbox-array-reactive-forms-handle-3885dde366ca

      我的问题是在一个更简单的示例中清理复选框数组。 没有时间浪费了..继续下一个任务..:)

      【讨论】:

        【解决方案7】:

        这是我的方法,我将其用于 ionic cordova Contacts 插件以从通讯录中获取多个联系人并添加选定的联系人。

        HTML

        <div *ngFor="let c of addressBook" tappable class="px-2">
          <input type="checkbox"  (change)="onChangeContact($event,c)">
          <p>{{ c.displayName }}</p>
         </div>
        

        TS

        onChangeContact($event, c) { 
            if ($event.target.checked) {
              this.tempArr.push(c);
            } else {
              let i: number = 0;
              this.tempArr.forEach((item: any) => {
                console.log(item);
                if (item.displayName == c.displayName) {
                  this.tempArr.splice(i, 1);
                  return;
                }
                i++;
              });
            }
          }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-05-02
          • 2020-10-13
          • 2021-01-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-11
          相关资源
          最近更新 更多