web-dev-qa-db-ja.com

*新しい入力要素を追加するときにすべてのフォーム値をリセットするため

私のローンに別のローンを追加できるボタンが付いたAngular2アプリがあります。私の* ngForも非常に単純です:

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

myLoansは、nameおよびamountパラメータを持つローンオブジェクトの配列です。ボタンもとてもシンプルです。

<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

「Legg tillån」ボタンを押すと、最初の入力の値がリセットされます

enter image description here

別の数値を入力しようとすると、ngModelは最初の入力に対して引き続き機能します

enter image description here

誰かがここで何が起こっているのか考えていますか?

12

AJT_82は問題に近いです。一意ではない名前が問題を引き起こしていますが、テンプレートのhtmlをこれに変更することで、さらに簡単な修正を行い、必要に応じてもう1つ修正することができます。

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

[]に名前を入れることの変更に注意してください。これにより、テンプレートが名前へのリンクを維持し、各ローンの名前が一意である限り識別子も維持されます。

pdate:名前が一意でない場合は、インデックスを追加して一意にすることができます。

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

nameが機能するため、一意のngModel属性を持たないフォームを使用していると99%確信しています。

Name属性は、個別のフィールドとして評価されるために一意である必要があります。 AngularはフォームのngModelを実際には気にしませんが、代わりに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>
5
AJT82

私はあなたのコードを試しましたが、それは私にとってはうまくいきます。コンパイラの問題である可能性があります。 ng2およびTypeScriptライブラリを最新バージョンに更新してみてください。次に、部分的なtsconfigファイルの例を示します。

{
  "compilerOptions": {
    "target": "es5",
    "typeRoots": ["node_modules/@types/"],
    "types": [
      "node",
      "es6-shim"
    ]
  }
}

また、変数宣言に「var」を使用しないでください。変数のスコープを維持するには、「let」を使用します。私はあなたの問題はvarの使用が原因であるかもしれないと思います。古いコンパイラを使用している場合、オブジェクトがめちゃくちゃになる可能性があります。

1
Merih Taze

[(ngModel)]を* ngForの反復子オブジェクトとして宣言したため、入力の値はゼロになります。また、空白のオブジェクトをmyLoansの配列にプッシュすると、ngModelは入力をゼロ(amountのデフォルト値)に変更します

例:

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を使用するのは悪い習慣です。(クリック)イベントとAngularセレクター)を使用して同じタスクを実行する別の方法があります。代わりにこれを試してください:

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

@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に感謝し、理由を非常によく説明しました!

1
MKJ