角反应形式隐藏输入不绑定?

时间:2017-09-28 21:38:35

标签: angular

我有一个反应形式,我从我的数据模型创建控件。最初,所有内容都按数字顺序排序,称为“processingOrder”。

在我的表单数组中,我使用*ngFor迭代控件并将索引存储在隐藏的form control中。如果我在表格中向上或向下移动记录,应用于隐藏字段的索引应该反映我的模型中的更改吗?

<form [formGroup]="rulesForm" (ngSubmit)="onSubmit(form)">
<div formGroupName="ruleData">
   <div formArrayName="rules">
      <div *ngFor="let child of rulesForm.controls.ruleData.controls.rules.controls; let i = index">
         <div formGroupName="{{i}}">
            <input type="text" placeholder="Rule Name" formControlName="name"/> &nbsp; 
            <input type="text" placeholder="Rule Description" formControlName="description"/> &nbsp;
            <input type="text" placeholder="Processing Order" formControlName="processingOrder"/> &nbsp;
            <button class="button" (click)="move(-1, i)">Move Up</button> &nbsp; 
            <button class="button" (click)="move(1, i)">Move Down</button>


            <!-- Why doesn't this update my model when it gets a new index? -->
            <input type="hidden" formControlName="processingOrder" [value]="i">


         </div>
      </div>
   </div>
</div>
<button type="submit">Submit</button>
</form>

我原本以为,在我的plunker中,处理订单号应该始终保持在1-5的顺序,并且每次向上或向下移动规则时,模型都会更新为它收到的新索引。

https://plnkr.co/edit/ZCgHPEaUM00aLxM6Sf9t?p=preview

2 个答案:

答案 0 :(得分:12)

formControlName指令具有ngModel输入,该输入绑定到控件的模型,并且从代码更改后将更新其视图上的所有实例。因此,只需将[value]="i"替换为[ngModel]="i + 1"

<input type="hidden" formControlName="processingOrder" [ngModel]="i + 1">

绑定到HTML输入的属性value[value]="i + 1")将更新视图上的当前输入,但不会更新控件的模型,因此不会影响具有相同控件名称的其他实例。

您还可以删除隐藏的输入并将[value]="i + 1"放在文本输入上:

<input type="text" 
       placeholder="Processing Order" 
       [ngModel]="i + 1"
       formControlName="processingOrder"/>

请注意,processingOrder的索引始终会覆盖ngFor的值i

答案 1 :(得分:0)

将此添加到上移/下移处理方法的底部,

move(shift, currentIndex) {
  const rules = this.rulesForm.get(['ruleData', 'rules']);

  let newIndex: number = currentIndex + shift;
  if(newIndex === -1) {
    newIndex = rules.length - 1;
  } else if(newIndex == rules.length) {
    newIndex = 0;
  }

  const currentGroup = rules.at(currentIndex);
  rules.removeAt(currentIndex);;
  rules.insert(newIndex, currentGroup)

  // logic to re-calculate processingOrder in the correct ascending order
  let i = 0;
  this.rulesForm.get(['ruleData', 'rules']).controls.forEach((elem) => {
    i++;
    elem.get('processingOrder').setValue(i);
  });
}

它基本上根据formArray长度按升序重新分配processingOrder编号。希望能帮助到你。 (确认它在plunker工作)

您不需要模板中的hidden input才能使用此功能。此外,如果您指定了多个输入控件(此处为&#39; text&#39;以及&#39; hidden&#39;对于&#39; processingOrder&#39;)的输入元素具有相同的{{1}那么它可能不会像你期望的那样以反应的形式发挥作用。