[英]Get value from all checked checkbox in angular
我正在使用 angular 创建测验应用程序,我有这样的代码
ngOnInit() {
this.myForm = this.fb.group({
lessonCode: "test",
answer: this.fb.array([])
});
}
onChange(email: string, code: string, isChecked: boolean) {
const emailFormArray = <FormArray>this.myForm.controls.answer;
if (isChecked) {
let array = new FormGroup({
questionCode: new FormControl(email),
emailCode: new FormArray([
new FormControl(code)
]),
});
emailFormArray.push(array);
} else {
let index = emailFormArray.controls.findIndex(x => x.value == email);
emailFormArray.removeAt(index);
}
}
产生这样的数组
Form values: {
"lessonCode": "test",
"answer": [
{
"questionCode": "pertanyaan2",
"emailCode": [
"option2"
]
},
{
"questionCode": "pertanyaan2",
"emailCode": [
"option1"
]
}
]
}
但我真正需要的是这样
Form values: {
"lessonCode": "test",
"answer": [
{
"questionCode": "pertanyaan2",
"emailCode": {
"option2",
"option1"
}
}
]
}
我怎样才能做到这一点? 任何想法都会非常有帮助
我在这里复制最少https://stackblitz.com/edit/angular-ca1jin?file=src%2Fapp%2Fapp.component.ts
我建议了另一种方法
如果我们创建一个 formGroup 像
this.myForm = this.fb.group({
lessonCode: "test",
answer: this.fb.array(this.users.map(x=>this.fb.group({
questionCode:x.code,
email:[[]]
})))
});
看到答案是一个FormGroup的FormArray,每个FormGroup有两个FormsControl,questionCode和email,那仍然是一个FormControl(但是存储了一个数组)。 您不需要与 FormArray 混淆。 一个 FormControl 可以存储一个数组、一个对象、一个字符串、一个数字等。 存储一个数组并不奇怪,例如 mat-select multiple 也存储一个数组
和往常一样,我们使用 formArrays 我们声明了一个 getter 来管理 .html
get answers()
{
return this.myForm.get('answer') as FormArray
}
嗯,形式有点复杂
<form [formGroup]="myForm">
<div formArrayName="answer">
<div *ngFor="let group of answers.controls;let i=index">
<p>{{users[i].code}}</p>
<div *ngFor="let user of users[i].email">
<input #check type="checkbox"
[value]="answers.at(i).value.email.indexOf(user.code)>=0"
(change)="onChange(i,user.code,check.checked)" >{{user.code}}<br>
</div>
</div>
</div>
</form>
看看我们如何使用[value]="answers.at(i).value.email.indexOf(user.code)>=0"
如果我们的“电子邮件”控件一开始是空的,那确实没有必要,但可能我们想要将来使用这种形式来显示结果,我们的“eamil”可以取值,例如“[option1]”
另一件要考虑的事情是我使用模板引用变量#check
并将其发送到函数 OnChange check.checked
我们在函数中收到了一个布尔值 -
我们的函数 OnChange 变得更简单
onChange(index:number, code: string, isChecked: boolean) {
const control=this.answers.at(index).get('email')
if (isChecked && control.value.indexOf(code)<0)
control.setValue([...control.value,code]
.sort((a:string,b:string)=>
this.users[index].email.findIndex(x=>x.code==a)>
this.users[index].email.findIndex(x=>x.code==b)?1:-1)
)
if (!isChecked && control.value.indexOf(code)>=0)
control.setValue(control.value.filter(x=>x!=code))
}
我喜欢在删除/添加元素之前检查是否存在
看到当检查为真时我们需要“排序”响应 - 否则我们收到响应,例如 [option2,option1] -如果我们的要求不需要我们可以删除排序 -
您可以创建一个函数来遍历每个答案并以您想要的模式返回一个对象。
您需要做的是将emailCode
添加为FormArray
而不是FormControl
,这样您就可以检查questionCode
是否已经存在,如果是,您可以将您选中的选项附加到emailCode
。
唯一需要改变的是你的onChange
方法
首先你array
变量,你需要添加FormArray
而不是FormControl
let array = new FormGroup({
questionCode: new FormControl(email),
emailCode: new FormArray([])
});
然后为您选中的选项创建一个FormControl
let codeOption = new FormControl(code)
最后,在您的if
条件中,检查 questionCode 是否已经存在以将您的 formControl 附加到它,或者创建一个新对象。
if (isChecked) {
if (emailFormArray.controls.some(obj => obj.get('questionCode').value == email)){
(<FormArray>emailFormArray.controls.find(obj => obj.get('questionCode').value == email).get('emailCode')).push(codeOption);
}else{
(<FormArray>array.get('emailCode')).push(codeOption)
emailFormArray.push(array)
}
}
为了更清楚,我已经修改了你的stackblitz以满足你的需求
我没有修改else
条件来删除您的FormArray
上的选项,但您只需要复制if
条件即可获取您的FormArray
上的FormArray
code
元素的emailCode
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.