本文介绍了如何将选中的值放入 Angular 模板驱动表单 (ngModel) 的数组中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使用模板驱动的表单,将 html 中的模型绑定到一个新实例,比如 Person.我未能成功地为复选框创建正确绑定到模型上的单个数组属性.
这个想法是数据将来自 api 或其他来源,通过 *ngFor
动态呈现复选框并将所选内容绑定到 Person 模型属性,这将是一个数字数组.例如:
class Person {名字:字符串;someCheckboxPropList: number[];}
数据可以是任何东西
const dynamicData = [{名称:'名称1',值:1},{名称:'name2',值:2}];
我的预期输出将类似于 [ 1, 2 ]
的内容,如果两个值都被检查,并且如果只检查第二个值 [ 2 ]
.
以下是 PersonComponent.ts 文件的示例
@Component({ ... })导出类 PersonComponent {提交=假;模型 = 新人();构造函数(){}提交(表单){this.submitted = true;控制台日志(表单);}}
我现在的组件 html 文件.
<input type="text" [(ngModel)] name="person.firstName"><div *ngFor="let dataItem of dynamicData" ><label>{{dataItem.name}}</label>
</表单>
这不起作用(无论如何都是示例代码).
解决方案
这个想法是有两个东西:Person 和 PersonForm,所以,例如
person={firstName:"Jessy",props:[1,2]//但personForm={firstName:"Jessy",props:[true,true]
所以,创建两个函数
createForm(person) {返回 {名字:person.firstName,道具:this.dynamicData.map(x => person.props.indexOf(x.value) >= 0)}}检索数据(personForm){让道具:数字[] = [];personForm.props.forEach((v, index) => {如果(五)props.push(this.dynamicData[index].value)})返回 {名字:personForm.firstName,道具:道具}}
好吧,我们已经拥有了我们需要的一切.当我们收到一个人时,创建一个 personForm ,它是我们在表单中更改的数据.在提交中只需调用retrieveData 来获取person 的值.
当我们让一个人创建一个personForm时,例如
this.service.getPerson().subscribe(person=>{this.personForm=createForm(person)})
我们的表格
<input name="firtName" [(ngModel)]="personForm.firstName"><div *ngFor="let dynamicData 项;let i=index"><input name="{{'prop'+i}}"type="checkBox" [(ngModel)]="personForm.props[i]">{{item.name}}
</表单>{{personForm|json}}<br/>{{retrieveData(personForm)|json}}
还有我们的 sendData 函数
sendData(personForm){console.log(this.retrieveData(personForm))}
我做了一个简单的stackblitz
更新
注意:我们可以使用 spred 操作符来定义属性,所以
createForm(person) {返回 {...person,//person的所有属性,但是道具:this.dynamicData.map(x => person.props.indexOf(x.value) >= 0)}}检索数据(personForm){让道具:数字[] = [];personForm.props.forEach((v, index) => {如果(五)props.push(this.dynamicData[index].value)})返回 {..personForm,//personForm的所有属性,但是道具:道具}}
注意2:在现实世界"中,人员来自服务.考虑服务获取/接收personForm"并将要转换的功能放在服务中的想法
//服务中获取人(){返回 this.httpClient.get("...").map(res=>this.createForm(res))}savePerson(personForm){return this.httpClient.post("...",this.retrieveData(personForm))}
I'm attempting to use template driven forms, binding to a model in the html to a new instance of lets say Person. I've been unsuccessful in creating a proper binding for checkboxes to a single array property on my model.
The idea is data will come from an api or other source, dynamically render checkboxes via *ngFor
and bind what is selected to the Person models property which would be an array of numbers. For example:
class Person {
firstName: string;
someCheckboxPropList: number[];
}
and data could be anything really
const dynamicData = [
{ name: 'name1', value: 1 },
{ name: 'name2', value: 2 }
];
my expected output would be something along the lines of [ 1, 2 ]
if both values where to be checked and if only the second was checked [ 2 ]
.
Here's a sample of what the PersonComponent.ts file might look like
@Component({ ... })
export class PersonComponent {
submitted = false;
model = new Person();
constructor() { }
onSubmit(form) {
this.submitted = true;
console.log(form);
}
}
And where I'm at with the components html file.
<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>
This does not work (and is sample code anyway).
解决方案
the idea is have two things: Person and PersonForm, so,e.g
person={firstName:"Jessy",props:[1,2]
//but
personForm={firstName:"Jessy",props:[true,true]
So, make two functions
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
}
}
Well, we have already all we need. When we received a person, create a personForm that it's the data we change in the form. In submit simply call to retrieveData to get the value of person.
When we have a person create a personForm,e.g.
this.service.getPerson().subscribe(person=>
{
this.personForm=createForm(person)
}
)
Our form
<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}}
And our sendData function
sendData(personForm)
{
console.log(this.retrieveData(personForm))
}
I make a simple stackblitz
Update
NOTE:We can use the spred operator to asing properties, so
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
}
}
NOTE2: In a "real world" the persons goes from a service. Consider the idea that service get/received the "personForm" and put the functions to transform in the service
//in service
getPerson()
{
return this.httpClient.get("...").map(res=>this.createForm(res))
}
savePerson(personForm)
{
return this.httpClient.post("...",this.retrieveData(personForm))
}
这篇关于如何将选中的值放入 Angular 模板驱动表单 (ngModel) 的数组中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!