【问题标题】:Angular reactive form hidden input not binding?角反应形式隐藏输入不绑定?
【发布时间】:2017-09-28 21:38:34
【问题描述】:

我有一个反应式表单,我在其中从我的数据模型创建控件。最初,所有内容都按名为“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

【问题讨论】:

    标签: angular


    【解决方案1】:

    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 覆盖

    2021 年更新 :) 请注意ngModel(带有反应形式指令)deprecation,因为 NG6:

    Angular v6 已弃用对使用 ngModel 输入属性和 ngModelChange 事件的响应式表单指令的支持,并计划在未来版本的 Angular 中删除。

    【讨论】:

    • 这似乎运作良好 - 当我从我的对象中删除规则时出现了一个小问题。如果我在删除之前没有移动任何规则,则在每次删除时这些规则将继续按照索引的正确顺序排列。但是,如果我移动一条规则然后删除一条规则,则删除记录所在位置的索引似乎保留了它的旧索引。我认为?最终在对象中留下 2 条具有相同处理顺序的记录。对这将如何发生有任何想法吗?
    • 我用“删除”按钮更新了你的 plunker,似乎工作正常。请更新我的 plunker (plnkr.co/edit/NvSkiutOQLeu9i41H1AT?p=preview) 以便我可以重现您提到的问题,然后我会尽力提供帮助
    • 谢谢,看来我的问题在别处。 ngModel 解决了我的问题。不知道它可以与反应形式一起使用。
    • 很高兴为您提供帮助:)。正如我已经说过的,ngModel 这里只是formControlName 指令(github.com/angular/angular/blob/master/packages/forms/src/…)的“@input”,它属于ReactiveFormsModule(不是FormsModule
    • 此解决方案的一些新问题:您似乎在与 formControlName 相同的表单字段上使用 ngModel。 Angular v6 中已弃用对使用 ngModel 输入属性和 ngModelChange 事件的响应式表单指令的支持,并将在 Angular v7 中删除
    【解决方案2】:

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

    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 即可使用。此外,如果您使用相同的formControlName 指定多个输入控件(此处为“处理订单”类型的“文本”和“隐藏”类型的输入元素),那么它可能不会像您期望的那样以反应形式工作。

    【讨论】:

      猜你喜欢
      • 2018-12-19
      • 2019-05-13
      • 1970-01-01
      • 2013-12-14
      • 1970-01-01
      • 2019-05-24
      • 2018-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多