【问题标题】:Angular2 - Reactive Forms w/ Arrays of DataAngular2 - 带有数据数组的反应式表单
【发布时间】:2017-07-22 09:27:52
【问题描述】:

我的组件中有一个表单设置,用户可以在其中修改最多三个班次容器,包括开始时间、结束时间和星期几。

不必重复一堆代码三次,我试图找出最动态的方法来解决这个问题。

这是我当前的单班 HTML:

<span formGroupName="slice" *ngFor="let slice of [1,2,3]">
   <table class="table table-condensed">
      <thead>
         <th></th>
         <th></th>
         <th></th>
         <th></th>
         <th></th>
         <th></th>
         <th></th>
         <th></th>
         <th style="text-align:center;">Enable</th>
      </thead>
      <tbody>
         <tr>
            <td class="col-md-2" style="text-align:center; vertical-align:middle">
               Time Slice {{ slice }}
            </td>
            <td>
               <select name="hour_start" class="form-control input-sm"  formControlName="hour_start">
                  <option value="{{ h }}" *ngFor="let h of hours">{{ h }}</option>
               </select>
            </td>
            <td>
               <select name="minute_start" class="form-control input-sm" formControlName="minute_start">
                  <option value="{{ m }}" *ngFor="let m of minutes">{{ m }}</option>
               </select>
            </td>
            <td>
               <select name="period_start" class="form-control input-sm" formControlName="period_start">
                  <option value="{{ p }}" *ngFor="let p of period">{{ p }}</option>
               </select>
            </td>
            <td style="text-align:center; vertical-align:middle;">-</td>
            <td>
               <select name="hour_end" class="form-control input-sm" formControlName="hour_end">
                  <option value="{{ h }}" *ngFor="let h of hours">{{ h }}</option>
               </select>
            </td>
            <td>
               <select name="minute_end" class="form-control input-sm" formControlName="minute_end">
                  <option value="{{ m }}" *ngFor="let m of minutes">{{ m }}</option>
               </select>
            </td>
            <td>
               <select name="period_end" class="form-control input-sm" formControlName="period_end">
                  <option value="{{ p }}" *ngFor="let p of period">{{ p }}</option>
               </select>
            </td>
            <td style="vertical-align:middle; text-align:center;"><input type="checkbox" (change)="toggleSlice(slice, true)"></td>
         </tr>
         <tr>
            <td class="col-md-2"></td>
            <td colspan="7">
               <table class="table table-condensed" formGroupName="days">
                  <tbody>
                     <tr>
                        <td *ngFor="let d of days">
                           <div class="checkbox">
                              <label>
                              <input type="checkbox" formControlName="day_{{ d }}"> {{ d }}
                              </label>
                           </div>
                        </td>
                     </tr>
                  </tbody>
               </table>
            </td>
         </tr>
      </tbody>
   </table>
</span>
<!-- Time Slice -->
</span>

这是我的组件:

this.transitionForm = this.fb.group({
            shift: this.fb.group({
                slice: this.fb.group({
                    hour_start: { value: '1', disabled: true },
                    minute_start: { value: '00', disabled: true },
                    period_start: { value: 'AM', disabled: true },
                    hour_end: { value: '1', disabled: true },
                    minute_end: { value: '00', disabled: true },
                    period_end: { value: 'AM', disabled: true },
                    days: this.fb.group({
                        day_Su: { value: '', disabled: true },
                        day_M: { value: '', disabled: true },
                        day_Tu: { value: '', disabled: true },
                        day_W: { value: '', disabled: true },
                        day_Th: { value: '', disabled: true },
                        day_F: { value: '', disabled: true },
                        day_Sa: { value: '', disabled: true }
                    })
                })
            })
        }); 

其他小细节是每个班次行都包含一个启用/禁用复选框,因此如果需要,我可以选择使用其他两个班次容器,否则,它们将被禁用。

现在使用 jQuery 之类的东西,我可以通过获取此复选框的父元素并以这种方式处理每组数据(移位)来完成此操作。不过,我的目标是不需要使用 jQuery 并找出响应式表单可以为这种情况提供什么。

问题:

我如何才能使用反应形式将这三个时间片(转换)形成更动态的设置,而不是为每个时间片硬编码一个片。反应式表单可以处理这个吗?

【问题讨论】:

    标签: javascript angular typescript angular-reactive-forms


    【解决方案1】:

    是的,您可以使用Form Arrays 动态添加和删除反应式表单的部分。

    有一篇很好的博客文章涵盖了这个here,我在下面包含了一些相关的文章

    组件

    ngOnInit() {
      // we will initialize our form here
      this.myForm = this._fb.group({
          name: ['', [Validators.required, Validators.minLength(5)]],
          addresses: this._fb.array([
            this.initAddress(),
          ])
        });
      }
    
    initAddress() {
        // initialize our address
        return this._fb.group({
          street: ['', Validators.required],
          postcode: ['']
        });
      }
    
    addAddress() {
      // add address to the list
      const control = <FormArray>this.myForm.controls['addresses'];
      control.push(this.initAddress());
    }
    
    removeAddress(i: number) {
      // remove address from the list
      const control = <FormArray>this.myForm.controls['addresses'];
      control.removeAt(i);
    }
    

    HTML

    <!-- list of addresses -->
    <div formArrayName="addresses">
      <div *ngFor="let address of myForm.controls.addresses.controls; let i=index">
        <!-- address header, show remove button when more than one address available -->
        <div>
          <span>Address {{i + 1}}</span>
          <span *ngIf="myForm.controls.addresses.controls.length > 1" (click)="removeAddress(i)">
          </span>
        </div>
    
        <!-- Angular assigns array index as group name by default 0, 1, 2, ... -->
        <div [formGroupName]="i">
          <!--street-->
          <div>
            <label>street</label>
            <input type="text" formControlName="street">
            <!--display error message if street is not valid-->
            <small [hidden]="myForm.controls.addresses.controls[i].controls.street.valid">
              Street is required
            </small>
          </div>
          <!--postcode-->
          <div>
            <label>postcode</label>
            <input type="text" formControlName="postcode">
          </div>
        <div>
      </div>
    </div>
    

    【讨论】:

      猜你喜欢
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 2017-09-03
      • 1970-01-01
      • 2019-11-02
      • 2017-12-30
      • 1970-01-01
      • 2017-04-10
      相关资源
      最近更新 更多