angular - 如何将检查值放入 Angular 模板驱动表单 (ngModel) 的数组中
问题描述
我正在尝试使用模板驱动的表单,将 html 中的模型绑定到让说Person的新实例。我未能成功地为我的模型上的单个数组属性的复选框创建正确的绑定。
这个想法是数据将来自 api 或其他来源,通过动态呈现复选框*ngFor
并将选择的内容绑定到Person模型属性,该属性将是一个数字数组。例如:
class Person {
firstName: string;
someCheckboxPropList: number[];
}
数据可以是任何东西
const dynamicData = [
{ name: 'name1', value: 1 },
{ name: 'name2', value: 2 }
];
我的预期输出将类似于 [ 1, 2 ]
if 两个值都在哪里被检查,如果只有第二个被检查[ 2 ]
。
下面是 PersonComponent.ts 文件的示例
@Component({ ... })
export class PersonComponent {
submitted = false;
model = new Person();
constructor() { }
onSubmit(form) {
this.submitted = true;
console.log(form);
}
}
我在哪里使用组件 html 文件。
<form (ngSubmit)="onSubmit(form)" #form="ngForm">
<input type="text" [(ngModel)] name="person.firstName">
<div *ngFor="let dataItem of dynamicData" >
<input
type="checkbox"
ngModel
name="dynamicData"
[value]="dataItem.value">
<label>{{dataItem.name}}</label>
</div>
</form>
这不起作用(无论如何都是示例代码)。
解决方案
这个想法是有两件事:Person和PersonForm,所以,例如
person={firstName:"Jessy",props:[1,2]
//but
personForm={firstName:"Jessy",props:[true,true]
所以,做两个函数
createForm(person) {
return {
firstName: person.firstName,
props: this.dynamicData.map(x => person.props.indexOf(x.value) >= 0)
}
}
retrieveData(personForm) {
let props: number[] = [];
personForm.props.forEach((v, index) => {
if (v)
props.push(this.dynamicData[index].value)
}
)
return {
firstName: personForm.firstName,
props: props
}
}
好吧,我们已经拥有了我们需要的一切。当我们收到一个人时,创建一个 personForm,它是我们在表单中更改的数据。在提交中只需调用retrieveData 来获取person 的值。
当我们让一个人创建一个personForm时,例如
this.service.getPerson().subscribe(person=>
{
this.personForm=createForm(person)
}
)
我们的表格
<form *ngIf="personForm" (submit)="sendData(personForm)">
<input name="firtName" [(ngModel)]="personForm.firstName">
<div *ngFor="let item of dynamicData;let i=index">
<input name="{{'prop'+i}}"
type="checkBox" [(ngModel)]="personForm.props[i]">{{item.name}}
</div>
<button>Submit</button>
</form>
{{personForm|json}}<br/>
{{retrieveData(personForm)|json}}
还有我们的 sendData 函数
sendData(personForm)
{
console.log(this.retrieveData(personForm))
}
我做了一个简单的stackblitz
更新
注意:我们可以使用 spred 运算符来创建属性,所以
createForm(person) {
return {
...person, //All the properties of person, but
props: this.dynamicData.map(x => person.props.indexOf(x.value) >= 0)
}
}
retrieveData(personForm) {
let props: number[] = [];
personForm.props.forEach((v, index) => {
if (v)
props.push(this.dynamicData[index].value)
}
)
return {
..personForm, //all the properties of personForm, but
props: props
}
}
注意2:在“现实世界”中,这些人来自服务。考虑服务获取/接收“personForm”并将要转换的功能放在服务中的想法
//in service
getPerson()
{
return this.httpClient.get("...").map(res=>this.createForm(res))
}
savePerson(personForm)
{
return this.httpClient.post("...",this.retrieveData(personForm))
}
推荐阅读
- javascript - 可以拿到原版吗克隆纯javascript后
- java - 在处理 3 中创建可点击的网格
- c# - 在我的代码中找不到错误,它是一个使用列表存储操作和数字的计算器?
- sql - 为什么我的 SQL 代码会引发转换错误?
- solr - Solr HTTP Api - 响应状态
- kubernetes - 如何将 kube-proxy 配置为仅从本地节点提供服务
- wpfdatagrid - WPF - 如何访问 GridView 模板单元格中的控件
- owl-api - IRI.getShortForm() 不能按预期使用空格和一些额外的符号
- wpf - 为 TreeView 格式化 HierachicalDatatemplate
- java - 秒后有 10 位小数的 Java SimpleDateformatter,无法转换为日期