* ng在添加新输入元素时重置所有表单值

时间:2017-04-27 17:27:46

标签: angular typescript data-binding ngfor ng-modal

我有一个带有按钮的Angular2应用程序,可以为我的贷款添加另一笔贷款。我的* ngFor也非常简单:

    <div *ngFor="let loan of myLoans">
      <label>{{loan.name}}</label>
      <input type="text" name="loan.name" [(ngModel)]="loan.amount">
    </div>

myLoans是包含nameamount参数的贷款对象数组。我的按钮也很简单。

<button id="addLoan" type="button" (click)="addLoan()">Legg til lån</button>

addLoan()函数:

addLoan(): void{
    var newLoan = new Loan();
    this.myLoans.push(newLoan);
}

我的问题是,当我在列表中添加新贷款时,我在其他贷款的输入字段中的任何值都会回到0或我在贷款对象的构造函数中设置的任何值。

加载应用会显示此图片

What now

输入数字

时,

ngModel工作正常

enter image description here

按下“Leggtillån”按钮后,第一个输入的值被重置

enter image description here

如果我尝试输入另一个数字,ngModel仍在为第一个输入工作

enter image description here

任何人都知道这里发生了什么?

5 个答案:

答案 0 :(得分:16)

AJT_82接近问题,因为非唯一名称会导致您出现问题,但是您可以通过将模板html更改为更简单的方式进行更简单的修复,还可以进行更多修改。此

<div *ngFor="let loan of myLoans">
  <label>{{loan.name}}</label>
  <input type="text" [name]="loan.name" [(ngModel)]="loan.amount">
</div>

注意在[]中输入名称的更改。这将确保模板维护名称的链接,只要每个贷款的名称是唯一的,标识符也是唯一的。

<强>更新 如果name不是唯一的,您可以为其添加索引,使其独一无二。

<div *ngFor="let loan of myLoans; let i=index">
  <label>{{loan.name}}</label>
  <input type="text" [name]="loan.name + '_' + i" [(ngModel)]="loan.amount">
</div>

答案 1 :(得分:4)

我99%确定您使用的是表单,而没有唯一的name属性,因为ngModel有效。

name属性必须是唯一的,才能作为单独的字段进行评估。 Angular并不真正关心表单中的ngModel,而是查看name属性。

请注意,您当前设置的name属性:name="loan.name"实际上只包含字符串文字loan.name而不是模型的实际值,因此名称不是唯一的。

因此,当您推送新的loan时,所有其他贷款都会获得与新推送值相同的值,因为所有字段都被评估为同一个。

可以通过在name属性中添加索引来轻松修复此问题,例如:

<div *ngFor="let loan of myLoans; let i=index">
  <label>{{loan.name}}</label>
  <input type="text" name="loan.name{{i}}" [(ngModel)]="loan.amount">
</div>

答案 2 :(得分:0)

输入的值变为零,因为您已将[(ngModel)]声明为* ngFor的迭代器对象。当你将一个空白的对象推送到myLoans的数组时,ngModel将输入更改为零(金额的默认值)

示例:

myLoans = [0, 1, 2, 3]

刷新页面时,[(ngModel))将数组的最后一个值绑定到输入(3)。

如果你在输入上写125,

然后您还要更改最后一个数组的值

myLoans = [0, 1, 2, 125]

如果您推送一个新元素,Angular将使用最后一个数组值刷新输入

myLoans = [0, 1, 2, 125, 0]

Input.value now = 0

我的意见:在* ngFor中使用ngModel是一个不好的实践,使用(click)事件和Angular Selector执行相同任务的另一种方法。试试这个:

<input #loan ..>
<button (click)="addLoan(loan.value)">Add Loan</button>

答案 3 :(得分:0)

我已经尝试过您的代码,它对我来说很好用。我假设它可能是编译器问题。尝试将ng2和typescript库更新到最新版本。这是一个部分tsconfig文件的示例:

this.router.navigateByUrl(this.router.url, { queryParams: {}, preserveQueryParams: false });

同时避免使用&#34; var&#34;用于变量声明。使用&#34;让&#34;保持变量范围。我认为你的问题可能是因为使用了var。如果您使用的是旧编译器,则可能会弄乱您的对象。

答案 4 :(得分:0)

@Joo_Beck建议使用[name]=loan.name而不是name='loan.name'。但这对我没有用。我刚刚添加了一个索引{{i}},其名称如下所示,效果很好。

<div *ngFor="let loan of myLoans; let i=index">
  <label>{{loan.name}}</label>
  <input type="text" name="loan.name{{i}}" [(ngModel)]="loan.amount">
</div>

@ AJT_82建议适用于我的解决方案。谢谢!

感谢@Cassiano,您很好地解释了原因!