【问题标题】:Retrieve data from checkboxes in form从表单中的复选框中检索数据
【发布时间】:2020-02-02 20:09:13
【问题描述】:

我的问题是我有一个表单,当用户提交表单时,我想接收用户提交的数据。此数据应包装在单个对象中。我在 Angular 中使用 formBuilder,但似乎最有可能使用 formBuilder 从<input> 标签检索数据(引用this post: 中的顶级答案“formControlName 仅适用于输入、选择和文本区域。任何具有“价值”属性的东西。”

我在构造函数中定义了一个表单并初始化了字段,使用了 formBuilder;

component.ts

constructor(private formBuilder: FormBuilder,
) {
  this.checkoutForm = this.formBuilder.group({
    selectedAccount: '',
    selectedContactInfo: '',
  });
}

在我的 html 中,我有两个地方可供用户选择;一个下拉菜单和一系列复选框。我的构造函数中的selectedAccount 应用于<mat-select>,效果很好;在提交表格时,我可以看到我选择了哪个帐户。但是,我似乎无法将formControlName="selectedContactInfo" 应用于复选框区域中的div;它返回空字符串。

component.html

<!-- DROPDOWN - WORKS PERFECT -->
<mat-form-field>
  <mat-label>CHOOSE ACCOUNT</mat-label>
  <mat-select formControlName="selectedAccount">
    <mat-option *ngFor="let account of accounts" [value]="account.name">{{account.name}}</mat-option>
  </mat-select>
</mat-form-field>

<!-- CHECKBOXES - DOESN'T RETRIEVE DATA WHEN FORM IS SUBMITTED -->
h2 class="mat-h2">CHOOSE TELEPHONE NUMBERS WE CAN CONTACT YOU ON</h2>
<div formControlName="selectedContactInfo" class="item-container">
  <mat-checkbox>{{contactInfo.privateMobile}}</mat-checkbox>
  <mat-checkbox>{{contactInfo.workMobile}}</mat-checkbox>
</div>

从复选框中,我想检索实际数据。因此,如果第一个复选框已被选中,我想接收 contactInfo.privateMobile 包含的任何数据,可能是一个字符串或 8 位整数,并将其分配给构造函数中的 selectedContactInfo,就像我为 @ 所做的那样987654332@ 和下拉菜单。

我希望selectedContactInfo 包含复选框的数据;如果两者都被选中,则返回两者的手机号码。如果选中一个,它将返回该数字等。我还尝试在构造函数中使用selectedContactInfo: [],因为它需要返回所有复选框的数据,但现在只返回null。

提前致谢。

编辑:供参考(如果有人想知道这一点),这是我在提交表单时检查数据以查看其是否包含正确信息的方式。不知道是否相关:

onSubmit(userData) {
  console.log(userData);
}

【问题讨论】:

  • 请用一些示例数据创建一个StackBlitz 示例。

标签: angular forms typescript angular-material


【解决方案1】:

请检查这个例子

@Component({
  template: `
    <form [formGroup]="form">
      <input type="checkbox" formControlName="rememberLogin"> Remember login
    </form>
    <p>Form value: {{ form.value | json }}</p>  
    <!-- {rememberLogin: true } -->
  `,
})
export class App {
  constructor(public fb: FormBuilder) {
    this.form = this.fb.group({
        rememberLogin: [true]
    });
  }  
}

【讨论】:

  • 感谢您的评论。 console.log 只是返回一个布尔值,表示该框是否已被实时点击。我希望将值“检查我!”作为 formBuilder.group 的一部分与表单的其他元素一起提交到单个对象中 - 也就是说,将其分配给 selectedContactInfo 或在那里初始化的其他变量。使用这种方法,我也可以解散 formBuilder。
  • 您想使用表单生成器来获取复选框中的值吗?
  • 是的,就像我使用表单构建器获取下拉菜单的值一样。我编辑了我想从复选框中收到的内容的原始帖子(就在 component.html 的代码下)
  • 请查看link类似的答案以及link
  • 如果给定的链接没有帮助,我还使用 input type="checkbox" 更新了我的答案,然后尝试给定的示例
【解决方案2】:

问题

您想要的输出是一个数字数组,而选择将返回truefalse,因为它是一个复选框。在这种情况下,表单包含的值与您想要的不同,您可以使用valueChanges 来检测特定FormControl 中的更改,并从FormControlFormArray 中提取所需的结果。

解决方案

既然你想要一个数组,你需要做的第一件事就是为selectedContactInfo创建一个FormArray

contactInfo = {
    privateMobile: 1800124152,
    workMobile: 1800124124
};

this.checkoutForm = this.formBuilder.group({
    selectedAccount: '',
    selectedContactInfo: this.formBuilder.array(Object.keys(this.contactInfo).map(key => false))
});

请注意,我们使用contactInfo 初始化FormArray。这将基本上从对象中获取键并创建一个长度相同的数组,其中包含false 值(因为最初复选框值是false)。当然,如果您需要默认选中它,则需要将选择映射到复选框,但为了这个示例,我们将从所有 false 值开始。

在模板中注册 FormArray

在模板中设置FormArrayName,以便我们从复选框中访问true/false 值。使用KeyValuePipe,因为我们正在迭代contactInfo,它是一个对象。

<div class="item-container" formArrayName="selectedContactInfo">
    <ng-container *ngFor="let contactNumber of contactInfo | keyvalue; let i = index">
        <mat-checkbox [formControlName]="i">{{contactNumber.value}}</mat-checkbox>
    </ng-container>
</div>

在 valueChanges 中映射 FormArray

现在,根据复选框的选择,selectContactInfo 将成为 true/false 值的数组。这不是我们想要的,所以我们将订阅valueChanges 并将数据映射到contactInfo 并将其存储在一个名为selectedContactInfo 的变量中(注意这与FormArray 不同)。

const control = this.checkoutForm.controls.selectedContactInfo;
this.subscription = control.valueChanges.subscribe(value => {
    this.selectedContactInfo = Object.keys(this.contactInfo).map((contactNo, index) => 
        control.value[index] ? this.contactInfo[contactNo] : null
    )
    .filter(contactNo => !!contactNo);
});

我们在这里所做的基本上是从FormArray 中获取true/false 数组,然后将其映射到contactInfo。如果复选框值为true,则返回数字,否则返回null。然后使用filter 过滤掉null 值。

别忘了取消订阅valueChanges

ngOnDestroy() {
    this.subscription.unsubscribe();
}

StackBlitz example

【讨论】:

  • 嘿纳什,非常感谢您的全面回答,非常感谢!明天我试过这个后我会报告!但是,我希望这也适用于我,因为您使用数字实例化 contactInfo,而我从 REST 服务填充复选框值。如果可行,我会接受你的回答!
  • Anytime :) 如果 REST 服务与我使用的示例数据相同,它应该不会有什么不同。如果您需要更清楚,我只是在看到@WaqarAli 在他的回答中的 cmets 中提供的链接后回答了类似的question。我没有找到对该问题的满意答案,所以我在那里提供了我自己的answer。我还在那里使用了一组对象,因为它似乎是一个更好的结构,并且比对象更容易使用。
  • 我还直接修改了该示例中的FormArray,不像这里我使用单独的变量。
【解决方案3】:

它不返回数据,因为你需要为复选框本身添加formControlName,你不能将它添加到div中。只需添加两个联系信息,然后使用具有值的那些,或者您可以从对象中删除空的。

【讨论】:

  • 感谢您的评论,我已经尝试过了。那是行不通的,因为它只返回一个布尔值,表示复选框是否已被选中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多