admin管理员组文章数量:1287511
The ponent model:
private SomeArray = [{ key: "Initial" }];
User can add/remove items dynamically:
addField() {
this.SomeArray.push({ key: Math.random().toString() });
}
removeField(index: number) {
this.SomeArray.splice(index, 1);
}
Template markup:
<div class="col-xs-12">
<button (click)="addField()" type="button">Add</button>
</div>
<div *ngFor="let field of SomeArray; let i = index;">
<input [(ngModel)]="field.key" #modelField="ngModel" [name]=" 'SomeArray['+i+'].key' " type="text" class="form-control" required />
<div [hidden]="modelField.pristine || !(modelField.errors && modelField.errors.required)" class="alert alert-danger">
Required error
</div>
<button (click)="removeField(i)" class="btn btn-danger">Remove</button>
</div>
This works untill user removes any item from SomeArray
. If I add some two items initially:
and remove the one with 1 index:
then after adding another item Angular treat it as item has both 0 and 1 index (the new item "occupies" both two inputs):
(item with key 0.1345... is not displayed)
It's worth to noting items of SomeArray
are as expected, but data binding fails. What can be the reason of it?
Update: Thanks to the ments of @Stefan Svrkota and @AJT_82 it's known for me the issue can be resolved by adding [ngModelOptions]="{standalone: true}"
to the needed input. But I couldn't stop thinking about the reason of the issue in my cause, without setting standalone
option (there is unique value for each name attribute so it's excepted nothing wrong here).
Finally I have found that behavior occurs when input elements are into <form>
tag only - Plunker sample here (enclosing of template with form tag is the reason that issue).
Any ideas of this behavior?
The ponent model:
private SomeArray = [{ key: "Initial" }];
User can add/remove items dynamically:
addField() {
this.SomeArray.push({ key: Math.random().toString() });
}
removeField(index: number) {
this.SomeArray.splice(index, 1);
}
Template markup:
<div class="col-xs-12">
<button (click)="addField()" type="button">Add</button>
</div>
<div *ngFor="let field of SomeArray; let i = index;">
<input [(ngModel)]="field.key" #modelField="ngModel" [name]=" 'SomeArray['+i+'].key' " type="text" class="form-control" required />
<div [hidden]="modelField.pristine || !(modelField.errors && modelField.errors.required)" class="alert alert-danger">
Required error
</div>
<button (click)="removeField(i)" class="btn btn-danger">Remove</button>
</div>
This works untill user removes any item from SomeArray
. If I add some two items initially:
and remove the one with 1 index:
then after adding another item Angular treat it as item has both 0 and 1 index (the new item "occupies" both two inputs):
(item with key 0.1345... is not displayed)
It's worth to noting items of SomeArray
are as expected, but data binding fails. What can be the reason of it?
Update: Thanks to the ments of @Stefan Svrkota and @AJT_82 it's known for me the issue can be resolved by adding [ngModelOptions]="{standalone: true}"
to the needed input. But I couldn't stop thinking about the reason of the issue in my cause, without setting standalone
option (there is unique value for each name attribute so it's excepted nothing wrong here).
Finally I have found that behavior occurs when input elements are into <form>
tag only - Plunker sample here (enclosing of template with form tag is the reason that issue).
Any ideas of this behavior?
Share Improve this question edited Jun 11, 2017 at 0:06 Ilya Loskutov asked Jun 10, 2017 at 18:24 Ilya LoskutovIlya Loskutov 2,2012 gold badges23 silver badges39 bronze badges 4- 1 stackoverflow./questions/41265761/… – Stefan Svrkota Commented Jun 10, 2017 at 18:26
- @Stefan Svrkota solved, thank) – Ilya Loskutov Commented Jun 10, 2017 at 18:34
-
@AJT_82 I think
[name]=" 'SomeArray['+i+'].key' "
returns unique name value (with index of iteration i)? am I wrong? – Ilya Loskutov Commented Jun 10, 2017 at 19:07 - @Mergasov Nevermind what I was babbling about :D Yeah, ngModelOptions is a good solution here since I guess you don't really need the name attribute here in the form (I assume it is), as you are using two-way-binding. – AVJT82 Commented Jun 10, 2017 at 19:24
1 Answer
Reset to default 13The reason why it happens is ngFor
mixes name
properties when you delete some item.
When you use ngModel
inside form
each ngModel
control will be added to form controls collection.
Let's see what happens if we have added three items and clicked on Remove
the second
1) Step1 - SomeArray[1].key
exists in collection controls
2) Step2 - SomeArray[1].key
has been removed from controls
collection
3) Step3 - Html looks like
4) Step4 We are adding a new item
So formGroup
returns existing item.
How we can solve it?
1) Don't wrap our controls in form
tag
2) Add ngNoForm
attribute to form
<form ngNoForm>
3) Use
[ngModelOptions]="{standalone: true}
With all three solutions above:
We can remove
[name]
property bindingWe can't use the built in Form group validation
4) Use trackBy for ngFor
template.html
<div *ngFor="let field of SomeArray; let i = index; trackBy: trackByFn">
ponent.ts
trackByFn(i: number) {
return i;
}
Plunker Example
This way our built in form will work properly
本文标签: javascriptngModel cannot detect array changes correctlyStack Overflow
版权声明:本文标题:javascript - ngModel cannot detect array changes correctly - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741279695a2369935.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论