Angular 2+从对象获取键值并渲染表单输入框失败,求解决方案
解决Angular中遍历对象渲染表单的问题
首先得说,你遇到的问题很典型——Angular的*ngFor指令不能直接遍历普通对象,它只认数组。你的detailsStruct是{0: "something", 5: "somethingElse"}这种键值对对象,直接用*ngFor="let s of detailsStruct"的话,Angular根本没法正确解析出每个键和值,自然渲染不出你想要的表单。
下面给你两种最常用的解决方案,挑适合你的来用:
方案一:用Angular内置的KeyValuePipe(最简单)
Angular从6.x版本开始就自带了KeyValuePipe,它能直接把对象转换成包含key和value属性的键值对数组,完美适配*ngFor。
修改你的模板代码如下:
<div class="form-group" *ngFor="let item of detailsStruct | keyvalue"> <div class="input-group"> <!-- 可以把键显示在输入框前面,方便用户看到对应关系 --> <span class="input-group-text">{{item.key}}</span> <input type="text" class="form-control" [ngModelOptions]="{standalone: true}" [(ngModel)]="item.value" placeholder="输入内容" name="detail-{{item.key}}" > </div> </div>
小提示:
KeyValuePipe默认会对键进行排序(数字键按数值大小排,字符串键按字典序),如果想保持对象原本的插入顺序,可以自定义一个排序函数:- 在
myComponent.ts里添加:// 保持原顺序的比较函数 keepOriginalOrder(a: any, b: any): number { return 0; } - 模板里改成:
*ngFor="let item of detailsStruct | keyvalue: keepOriginalOrder"
- 在
方案二:在组件内把对象转成数组(更灵活)
如果不想用管道,也可以在组件里手动把对象转换成键值对数组,这样你能更自由地处理数据(比如过滤、修改键值等)。
在myComponent.ts里修改赋值逻辑:
// 先赋值 this.detailsStruct = this.newParameter.struct; // 把对象转换成键值对数组 this.detailsArray = Object.entries(this.detailsStruct).map(([key, value]) => ({ key: key, value: value }));
然后在模板里遍历这个数组:
<div class="form-group" *ngFor="let item of detailsArray; let i = index"> <div class="input-group"> <span class="input-group-text">{{item.key}}</span> <input type="text" class="form-control" [ngModelOptions]="{standalone: true}" [(ngModel)]="item.value" placeholder="输入内容" name="detail-{{i}}" > </div> </div>
顺便说下你原代码里的问题
- 直接用
*ngFor遍历对象时,s拿到的是对象的值(比如"something"),不是键值对,所以[(ngModel)]="s.value"会报错,因为字符串没有value属性; name="{{s[i]}}"逻辑完全错误,s是值,i是循环索引,两者没有关联,会导致表单控件的name属性混乱。
内容的提问来源于stack exchange,提问作者GigiProve
相关产品推荐
相关产品推荐

