私のローンに別のローンを追加できるボタンが付いた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に戻るか、ローンオブジェクトのコンストラクターで設定した値に戻ることです。
アプリをロードするとこの画像が表示されます
数値を入力するとngModelが機能します
「Legg tillån」ボタンを押すと、最初の入力の値がリセットされます
別の数値を入力しようとすると、ngModelは最初の入力に対して引き続き機能します
誰かがここで何が起こっているのか考えていますか?
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>
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>
私はあなたのコードを試しましたが、それは私にとってはうまくいきます。コンパイラの問題である可能性があります。 ng2およびTypeScriptライブラリを最新バージョンに更新してみてください。次に、部分的なtsconfigファイルの例を示します。
{
"compilerOptions": {
"target": "es5",
"typeRoots": ["node_modules/@types/"],
"types": [
"node",
"es6-shim"
]
}
}
また、変数宣言に「var」を使用しないでください。変数のスコープを維持するには、「let」を使用します。私はあなたの問題はvarの使用が原因であるかもしれないと思います。古いコンパイラを使用している場合、オブジェクトがめちゃくちゃになる可能性があります。
[(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>
@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に感謝し、理由を非常によく説明しました!