每个表格行的反应形式 [英] Reactive form for each table row

查看:26
本文介绍了每个表格行的反应形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Angular 2,我想分别验证每一行中的控件.但我没有办法做到这一点.我希望它只使用反应式形式而不是使用模板驱动的方法来完成.我想要每个 上的 [formGroup].任何帮助将不胜感激.以下是我的代码结构:

<tbody *ngFor="let one of allTeamDetails"[ngClass]="{'alternate-row-color': $even}"><tr><td class="td-data first-column"><input type="text" class="input-text form-control"[值]="single.first_name"></td><td class="td-data second-column"><input type="text" class="input-text form-control"[值]="single.last_name"></td><td class="td-data第三列"><input type="email" class="input-text form-control"[值]="single.email"></td><td class="td-data 第四列"><select class="selection-dropdown width-80-percent"[值]="single.user_role"><option *ngFor="let singleRole of allUserRole"value="{{singleRole.name}}">{{setUserRoleAndType(singleRole.name)}}</option></选择></td><td class="td-data 第五列" ><input type="password" class="input-text form-control"></td><td class="td-data第六列" ><input type="password" class="input-text form-control"></td><td class="td-data save-send-tm-data"><button class="btn save-user-details save-sub-account-details"type="button" data-toggle="tooltip" title="保存"><i class="fa fa-floppy-o" aria-hidden="true"></i></td><td class="td-data save-send-tm-data"><按钮类型=按钮"class="btn save-user-details save-sub-account-details"数据切换=工具提示"标题=发送消息"(点击)="openSendMessageModal(single.email)"><i class="fa fa-envelope" aria-hidden="true"></i></td><tr></tbody>

解决方案

使用 formArray.您要做的是创建一个 formGroup(主表单),其中包含多个较小的 formGroup.每个较小的 fromGroups 将在您的 *ngFor 中重复.

您的表单应如下所示:

<!--这是您的主表格--><form [formGroup]="teamForm"><!--使用 formArray 创建多个更小的表单'--><div formArrayName="memberDetails"><div *ngFor="let one of allTeamDetails; let $index=index"><div [formGroupName]="$index"><div><!--每个重复项的字段属性--><input placeholder="First Name" type="text" formControlName="firstName"/>

<div><input placeholder="Last Name" type="text" formControlName="lastName"/>

</表单>

在您的组件中,您可以使用 angular 的 formBuilder 来帮助构建表单.

在你的构造函数中:

 构造函数(私有 formBuilder:FormBuilder){this.teamForm = this.formBuilder.group({成员详细信息:this.formBuilder.array([])});}

现在您可以初始化重复模型的每个属性.然后,您可以自定义每个字段的每个验证器.请注意打字稿文件中与 html 中的属性相对应的属性.我在 ngOnInit 中完成所有这些,以便属性可以在呈现之前绑定到 html.

 ngOnInit() {this.teamForm = this.formBuilder.group({成员详细信息:this.formBuilder.array(this.allTeamDetails.map(x => this.formBuilder.group({firstName: [x.first_name, [Validators.required, Validators.minLength(2)]],lastName: [x.last_name, [Validators.required, Validators.minLength(2)]]})))})}

毕竟,添加验证消息非常简单.这样做有什么好处?

  1. 因为每个实例现在都是一个单独的 formGroup,所以您可以将验证逻辑自定义到非常精细的级别.

  2. 如上所述,您可以订阅每个较小表单的每个 valueChange,直至每个字段.例如,如果您想订阅第一个团队成员名字的字段更改,您可以这样做:

     this.teamForm.controls.memberDetails.controls[0]//获取第一个实例!.controls.firstName//获取formControlName的firstName.valueChange.subscribe(x=>console.log('值改变了!))

  3. 如果您想验证主表单,您也可以这样做.

已经创建了一个 plnkr,只为您 :)

I'm using Angular 2 and I want to validate controls in each row separately. But I'm not getting any way to do that. I want it to be done using reactive forms only and not using template-driven approach. I want [formGroup] on each <tr>. Any help will be appreciated. Below is the structure of my code:

<tbody *ngFor="let single of allTeamDetails"                
       [ngClass]="{'alternate-row-color': $even}">
  <tr>
    <td class="td-data first-column">
      <input type="text" class="input-text form-control" 
             [value]="single.first_name">
    </td>
    <td class="td-data second-column">
      <input type="text" class="input-text form-control" 
             [value]="single.last_name">
    </td>
    <td class="td-data third-column">
      <input type="email" class="input-text form-control" 
             [value]="single.email">
    </td>
    <td class="td-data fourth-column">
      <select class="selection-dropdown width-80-percent" 
              [value]="single.user_role">
        <option *ngFor="let singleRole of allUserRole"      
                value="{{singleRole.name}}"> 
                {{setUserRoleAndType(singleRole.name)}}</option>
      </select>
    </td>
    <td class="td-data fifth-column" >
      <input type="password" class="input-text form-control">
    </td>
    <td class="td-data sixth-column" >
      <input type="password" class="input-text form-control">
    </td>
    <td class="td-data save-send-tm-data">
      <button class="btn save-user-details save-sub-account-details"                                                      
              type="button" data-toggle="tooltip" title="Save">
        <i class="fa fa-floppy-o" aria-hidden="true"></i>
      </button>
    </td>
    <td class="td-data save-send-tm-data">
      <button type="button"                                      
              class="btn save-user-details save-sub-account-details"  
              data-toggle="tooltip" title="Send Message"                       
              (click)="openSendMessageModal(single.email)">
        <i class="fa fa-envelope" aria-hidden="true"></i> 
      </button>
    </td>
  <tr>
</tbody>

解决方案

Use formArray. What you will do is you create a formGroup (master form) that contains multiple, smaller formGroup. Each smaller fromGroups will be what is repeated in your *ngFor.

Your form should look something like this:

<!--This is your master form-->
<form [formGroup]="teamForm">
  <!--Use formArray to create multiple, smaller forms'-->
  <div formArrayName="memberDetails">
    <div *ngFor="let single of allTeamDetails; let $index=index">
      <div [formGroupName]="$index">
        <div>
          <!--your field properties of every repeated items-->
          <input placeholder="First Name" type="text" formControlName="firstName" />
        </div>
        <div>
          <input placeholder="Last Name" type="text" formControlName="lastName" />
        </div>
      </div>
    </div>
  </div>
</form>

In your component, you can use angular's formBuilder to help to build a the form.

In your constructor:

  constructor(private formBuilder: FormBuilder) {
    this.teamForm = this.formBuilder.group({
      memberDetails: this.formBuilder.array([])
    });
  }

Now you can initialize every property of your repeated models. You can then customise each validators of each field. Note the properties in your typescript file that corresponds to the ones in html. I do all these in ngOnInit so that the properties can binded to the html before they are rendered.

  ngOnInit() {   
    this.teamForm = this.formBuilder.group({
      memberDetails: this.formBuilder.array(
        this.allTeamDetails.map(x => this.formBuilder.group({
          firstName: [x.first_name, [Validators.required, Validators.minLength(2)]],
          lastName: [x.last_name, [Validators.required, Validators.minLength(2)]]
        }))
      )
    })
  }

After all these, adding validation messages are very trivial. The benefits of doing it this way?

  1. because each instance is now a single formGroup by itself, you can customize your validation logic down to a very granular level.

  2. As the point above, you can subscribe to each valueChange of each smaller forms, down to each single field. For example, if you want to subscribe to first team member's first name's field change, you can do this:

      this.teamForm
       .controls.memberDetails
       .controls[0] //get the first instance!
       .controls.firstName  //get the firstName formControlName
       .valueChange 
       .subscribe(x=>console.log('value changed!))
    

  3. In the event if you want to validate the master form, you can do so as well.

Have created a plnkr, just for you :)

这篇关于每个表格行的反应形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆