我删除地址并添加新地址时遇到错误。以前的地址被新的地址覆盖。
我创建了一个小型演示应用程序来展示我的问题:
github:https://github.com/kolomu/HeroDemo
stackblitz:https://stackblitz.com/edit/angular-gitter-5o6ydi
并不是模型是错误的,不知何故角度渲染的视图没有正确更新。
查看:
<form #heroForm="ngForm">
<div class="form-group">
<div class="addresses" *ngFor="let address of model.addresses; let i=index">
<label for="address-{{i}}">Address {{i}}</label>
<input type="text" class="form-control" [(ngModel)]="address.location" name="location-{{i}}">
<button class="btn btn-danger" (click)="remove(address)">Remove Address</button>
</div>
</div>
<button class="btn btn-primary" (click)="add()">Add Address</button>
</form>
组件类:
export class HeroFormComponent {
model = new Hero(18, 'Dr IQ', [new Address(1,'main','Earth'), new Address(9001,'sub','Moon')]);
remove(address) {
const index = this.model.addresses.findIndex(
address => address.id === address.id
);
this.model.addresses.splice(index, 1);
}
add(){
this.model.addresses.push(new Address());
}
}
数据模型:
export class Address {
constructor(public id?: number, public type?:string, public location?: string) { }
}
export class Hero {
constructor(
public id: number,
public name: string,
public addresses: Address[]
) { }
}
GIF-Image展示问题: https://gfycat.com/DelightfulSpiffyBetafish
答案 0 :(得分:1)
一个问题是您对address
方法的参数和remove
中的参数使用相同的名称findIndex
。因此,比较address.id === address.id
会为测试的第一个项目返回true
,因为它会将项目与自身进行比较。
remove(address) {
const index = this.model.addresses.findIndex(
address => address.id === address.id <-- Always true!
);
...
}
您应该为_address
中的参数使用其他名称,例如findIndex
(如this stackblitz所示):
remove(address) {
const index = this.model.addresses.findIndex(
_address => _address.id === address.id
);
...
}
或者您可以将索引作为参数传递给remove
,as suggested by Embrioka。
在您的代码示例中,在删除第一个地址后添加新地址时,这两个字段显示相同的数据(新地址的值)。这很奇怪,因为模板和代码中的一切看起来都很好。根据我的测试,问题来自于新输入元素的名称与之前用于其他元素的名称相同。在您的模板中,如果您替换:
name="location-{{i}}"
与
name="location-{{address.id}}"
只要每个address.id
都是唯一的,问题就会消失。显然,为不同的项重复使用相同的名称可以防止输入内容被Angular正确更新。
答案 1 :(得分:1)
不要传递整个地址,只传递索引:
<div class="form-group">
<div class="addresses" *ngFor="let address of model.addresses; let i=index">
<label for="address-{{i}}">Address {{i}}</label>
<input type="text" class="form-control" [(ngModel)]="address.location" name="location-{{i}}">
<button class="btn btn-danger" (click)="remove(i)">Remove Address</button>
</div>
</div>
在ts:
remove(index) {
this.model.addresses.splice(index, 1);
}
使用此解决方案,您甚至无需找到索引。
您的解决方案的问题与之前的评论者提到的内容以及您的id将是未定义的,因此在add方法中只需定义ID或在查找索引时选择另一个属性!