使用angular中的patchValue将值修补到复选框 [英] Patch values to checkbox using patchValue in angular
问题描述
我正在尝试重新使用我的 create-form
来编辑表单的值.创建表单时,我的复选框正在按要求工作.当我单击编辑表单时,这些值不会修补到我的复选框.下面是我尝试过的代码:
I'm trying to re-use my create-form
to edit the values of the form. My checkbox is working as per requirement while creating a form. When I click on edit form, the values aren't patching to my checkbox. Below is my code which I have tried:
<div class="form-row">
<div class="form-group col-sm-6">
<label>Authorized To</label>
<br>
<label *ngFor="let choice of authorized; let i=index">
<input type="checkbox" [value]="choice" (change)="onCheckChange($event)" [checked]="checkedVal"
formArrayName="authorized" type="checkbox[class.invalid]="! formGrowLicense.controls['authorized'].valid && formGrowLicense.controls['authorized'].touched ">
{{choice}}
</label>
<div *ngIf="!formGrowLicense.controls['authorized'].valid && (formGrowLicense.controls['authorized'].touched || isSubmitted)">
<div class="invalid-feedback" style="display: block;">Please enter authorized to</div>
</div>
</div>
</div>
ts
authorized: any = ['CULTIVATE', 'HARVEST', 'PROCESS']; //displaying list of checkbox
constructor() {
this.formGrowLicense = this.formBuilder.group({
businessName: ['', Validators.required],
authorized: new FormArray([], [Validators.required])
});
}
getGrowLicense(id) {
this.httpService.getGrowLicenseById(id).subscribe(
response => {
this.patchGrowLicense(response);
this.checkedVal = response.authorisedTo; // tried storing response in this variable ['CULTIVATE','HARVEST']
},
(err: any) => console.log(err)
);
}
patch(licenseObj){
this.formGrowLicense.patchValue({
businessName:licenseObj.companyName,
authorized: licenseObj.authorisedTo, // here i'm getting response ['CULTIVATE','HARVEST']. Need to patch these two values as checked in checkbox
});
}
onCheckChange(event) {
this.formArray = this.formGrowLicense.get(
'authorized'
) as FormArray;
/* Selected */
if (event.target.checked) {
console.log(event.target.value);
// Add a new control in the arrayForm
this.formArray.push(new FormControl(event.target.value));
} else {
/* unselected */
// find the unselected element
let i = 0;
this.formArray.controls.forEach((ctrl: FormControl) => {
if (ctrl.value == event.target.value) {
// Remove the unselected element from the arrayForm
this.formArray.removeAt(i);
return;
}
i++;
});
}
}
推荐答案
您有一个FormControls的FormArray,该数组接受true/false值和已接收值以及固定数组中的字符串数组,因此首先需要转换真/假数组
You has an FormArray of FormControls that takes values true/false and received and array of strings among a fixed array, so first you need transform the array received in an array of true/false
第一种方法
首先,我们将使用formArray创建一个Form.和往常一样,我们可以管理表单数组,我们需要创建一个返回表单数组的吸气剂
First we are going to create a Form with a formArray. As always we can manage a form array we need to create a getter that return our formArray
//our getter formArray
get authorizedArray()
{
return this.formGrowLicense.get('authorized') as FormArray
}
ngOnInit()
{ //we create the formArray
this.formGrowLicense=new FormGroup({
businessName:new FormControl(),
authorized:new FormArray(this.authorized.map(x=>new FormControl(false)))
})
}
请参见创建formArray的方法是使用 new FormArray(.. here和formControls ..)数组
.并且,创建formControls的formArray的方法是映射".数组"this.autorized"的每个元素到FormControl.
See that the way to create the formArray is using new FormArray(..here and array of formControls..)
. And the way to create the formArray of formControls is "mapping" each element of the array "this.autorized" to a FormControl.
要使用一系列.html
To manage in a series of inputs we using this .html
<form [formGroup]="formGrowLicense">
<input formControlName="businessName">
<!--we use formArrayName in a div-->
<div formArrayName="authorized">
<!--we iterate over autorizedArray.controls
remember our getter of the formArray? -->
<div *ngFor="let control of authorizedArray.controls;let i=index">
<!--we use [formControlName]=i -->
<label><input type="checkbox" [formControlName]="i">{{authorized[i]}}</label>
</div>
</div>
</form>
和往常一样,我们使用.html中的(仅用于检查)检查是否还可以
As always, we check if it's all ok using (only for check) in the .html
<pre>
{{formGrowLicense?.value|json}}
</pre>
看看我们如何遍历formArrayControls并使用索引在授权标签中显示[i]
See how we iterate over the formArrayControls, and use the index, to show in the label authorized[i]
好吧,我们还知道如何控制表单数组,所以接下来的问题是:我们如何向formArray提供值?
Well, We know yet how control a form array, so the next question: how we feed the formArray with the values?
请记住,我们收到了一些类似的信息,例如
Remember that we received some like, e.g.
{
businessName:'my business name'
authorized:['CULTIVATE', 'PROCESS']
}
当我们收到数据中的值时,我们可以使用类似的
when we received the value in data we can use some like
this.formGroupLicense.patchValue(
{
businessName:data.businessName,
authorized:this.authorized.map(x=>data.authorized.indexOf(x)>=0)
}
看看如何转换"data.authorize".并在包含3个元素的数组中包含0、1,2或3个元素的数组,它们的值分别为true或false
See how transform the "data.authorize" and array with 0,1,2 or 3 elements in an array of 3 elements that takes values true or false
好吧,我们需要做的最后一项工作是,在提交时,使用formArray的值(例如[true,false,false]来获取字符串数组
Well, the last work we need is, in submit, use the values of the formArray (e.g. [true,false,false] to get an array of strings
submit(form)
{
if (form.valid)
{
const data={
businessName:form.value.businessName
authorize:form.value.authorized.map(
(x,index)=>x?this.authorized[index]:null)
.filter(x=>x)
}
console.log(data) //<--here we has the data we send to the service
}
}
是的,我们将 [true,false,false]
映射到 ['CULTIVATE',null,null]
并进行过滤,只希望不为null的元素<代码> ['CULTIVATE']
Yes, we map the [true,false,false]
to ['CULTIVATE',null,null]
and filter and only want elements that are not null ['CULTIVATE']
好吧,使用pathValue没问题,但是为什么我们不创建一个返回带有所需数据的formGroup的函数
Well, use pathValue is ok but why we not create a function that return a formGroup with the data we want
createFormGroup(data:any=null)
{
data=data||{businessName:null,authorize:[]}
return new FormGroup({
businessName:new FormControl(data.businessName),
authorized:new FormArray(this.authorized
.map(x=>new FormControl(data.authorized.indexOf(x)>=0)))
})
}
所以,当我们收到数据时,我们唯一需要的就是使用
So, when we received the data the only thing we need is use
this.formGroupLicense=this.createFormGroup(data)
第二种方法
我们有一个类似
this.formGrowLicense=new FormGroup({
businessName:new FormControl(),
authorized:new FormControl()
})
是的!授权是存储数组的FormControl.如果您看到多个物料已选中,则为该方法.为此,您可以检查 SO 使用自定义formControl.让我解释一下(我不需要customFormControl)
YES! authorized is a FormControl that store an array. If you see the material multi checked is this approach. For this you can check this SO with use a custom formControl. Let me explain (I don't want a customFormControl)
我们有一个辅助数组,它具有两个属性"name".和值"我们想得到一些类似的东西
We has an auxiliary array with two properties "name" and "value" we want to get some like e.g.
authorizedAux: any = [{name:'CULTIVATE',value:true},
{name:'HARVEST',value:false},
{name:'PROCESS',value:true}]
所以我们添加了一个功能
So we add a function
setAutorized(data: string[]) {
this.authorizedAux = this.authorized.map(x => ({
name: x,
value: data.indexOf(x) >= 0
}));
}
另一个函数解析
parse() {
const result=this.authorized
.map((x, index) => (this.authorizedAux[index].value ? x : null))
.filter(x => x);
return result.length>0?result:null
}
然后我们可以创建一个使用ngModel,ngModelChange和ngModelOptions来更改FormControl值的html
then we can has an html that use ngModel, ngModelChange and ngModelOptions to change the value of the FormControl
<form [formGroup]="form">
<input formControlName="businessName">
<div *ngFor="let control of authorizedAux">
<label>
<input type="checkbox"
[ngModel]="control.value"
(ngModelChange)="control.value=$event;form.get('authorized').setValue(parse())"
[ngModelOptions]="{standalone:true}"
>{{control.name}}</label>
</div>
</form>
请记住,收到数据后,我们需要调用函数setAutorized
Remember that, when received the data we need call to the function setAutorized
请参见 stackblitz中的两种方法
这篇关于使用angular中的patchValue将值修补到复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!