针对 ngFor 变量的 Angular2 ngModel
Angular2 ngModel against ngFor variables
是否不能(或尚不能)对来自 ngFor
的值使用 ngModel
? Angular 是在试图保护我免受糟糕表现的影响吗?
效果很好:http://jsfiddle.net/langdonx/n5pjgev6/
<input type="text" [(ng-model)]="value">{{value}}
效果不是很好:http://jsfiddle.net/langdonx/n5pjgev6/1
<li *ng-for="#name of names">
<input type="text" [(ng-model)]="name">{{name}}
</li>
EXCEPTION: Cannot reassign a variable binding name
我也尝试绑定到数组,这...有点管用,但会劫持焦点并引发异常:http://jsfiddle.net/langdonx/n5pjgev6/2/
<li *ng-for="#name of names; #i = index">
<input type="text" [(ng-model)]="names[i]">{{name}}
</li>
EXCEPTION: LifeCycle.tick is called recursively
编辑:
我可以使用更直接的方法解决 LifeCycle.tick
问题,但焦点仍然被盗,因为 ngFor
重绘了东西:http://jsfiddle.net/langdonx/n5pjgev6/3/
<li *ng-for="#name of names; #i = index">
<input type="text" [value]="names[i]" (input)="names[i] = $event.target.value">{{names[i]}}
</li>
我认为 ngFor
不喜欢跟踪数组元素,这些元素是具有 ngModel
的原始值。
如果您删除循环内的 ngModel
,它会起作用。
当我 update jsfiddle 和 :
时它也有效
this.names = [{name: 'John'}, {name: 'Joe'}, {name: 'Jeff'}, {name: 'Jorge'}];
和
<li *ng-for="#n of names"><input type="text" [(ng-model)]="n.name">{{n.name}}</li>
一个解决方案是通过其索引引用 ngModel
中的值。因此[(ngModel)]="names[index]"
.
但这还不够,因为 *ngFor
按价值跟踪项目。一旦更改了值,就无法跟踪旧值。所以我们需要将跟踪功能更改为 return 一个索引,因此 trackBy: trackByIndex
.
此问题已解释 here。
解法:
@Component({
selector: 'my-app',
template: `
<div>
<input type="text"
*ngFor="let name of names; let nameIndex = index; trackBy: trackByIndex"
[(ngModel)]="names[nameIndex]"/>
<br/>
{{ names | json }}
</div>
`,
})
export class App {
names: string[];
constructor() {
this.names = ['a', 'b', 'c'];
}
public trackByIndex(index: number, item) {
return index;
}
}
是否不能(或尚不能)对来自 ngFor
的值使用 ngModel
? Angular 是在试图保护我免受糟糕表现的影响吗?
效果很好:http://jsfiddle.net/langdonx/n5pjgev6/
<input type="text" [(ng-model)]="value">{{value}}
效果不是很好:http://jsfiddle.net/langdonx/n5pjgev6/1
<li *ng-for="#name of names">
<input type="text" [(ng-model)]="name">{{name}}
</li>
EXCEPTION: Cannot reassign a variable binding name
我也尝试绑定到数组,这...有点管用,但会劫持焦点并引发异常:http://jsfiddle.net/langdonx/n5pjgev6/2/
<li *ng-for="#name of names; #i = index">
<input type="text" [(ng-model)]="names[i]">{{name}}
</li>
EXCEPTION: LifeCycle.tick is called recursively
编辑:
我可以使用更直接的方法解决 LifeCycle.tick
问题,但焦点仍然被盗,因为 ngFor
重绘了东西:http://jsfiddle.net/langdonx/n5pjgev6/3/
<li *ng-for="#name of names; #i = index">
<input type="text" [value]="names[i]" (input)="names[i] = $event.target.value">{{names[i]}}
</li>
我认为 ngFor
不喜欢跟踪数组元素,这些元素是具有 ngModel
的原始值。
如果您删除循环内的 ngModel
,它会起作用。
当我 update jsfiddle 和 :
时它也有效this.names = [{name: 'John'}, {name: 'Joe'}, {name: 'Jeff'}, {name: 'Jorge'}];
和
<li *ng-for="#n of names"><input type="text" [(ng-model)]="n.name">{{n.name}}</li>
一个解决方案是通过其索引引用 ngModel
中的值。因此[(ngModel)]="names[index]"
.
但这还不够,因为 *ngFor
按价值跟踪项目。一旦更改了值,就无法跟踪旧值。所以我们需要将跟踪功能更改为 return 一个索引,因此 trackBy: trackByIndex
.
此问题已解释 here。
解法:
@Component({
selector: 'my-app',
template: `
<div>
<input type="text"
*ngFor="let name of names; let nameIndex = index; trackBy: trackByIndex"
[(ngModel)]="names[nameIndex]"/>
<br/>
{{ names | json }}
</div>
`,
})
export class App {
names: string[];
constructor() {
this.names = ['a', 'b', 'c'];
}
public trackByIndex(index: number, item) {
return index;
}
}