angular - 使用角度中的 patchValue 将值修补到复选框
问题描述
我正在尝试重新使用 mycreate-form
来编辑表单的值。我的复选框在创建表单时按要求工作。当我单击编辑表单时,这些值不会修补到我的复选框。以下是我尝试过的代码:
<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 和接收的值以及固定数组中的字符串数组,所以首先你需要将接收到的数组转换为 true/false 数组
第一种方法
首先,我们将创建一个带有 formArray 的表单。与往常一样,我们可以管理一个表单数组,我们需要创建一个 getter 来返回我们的 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 and array of formControls..)
. 创建formControls的formArray的方法是将数组“this.autorized”的每个元素“映射”到FormControl。
为了管理一系列输入,我们使用这个 .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 中使用(仅用于检查)检查是否一切正常
<pre>
{{formGrowLicense?.value|json}}
</pre>
看看我们如何遍历 formArrayControls,并使用索引,在标签中显示 authorized[i]
好吧,我们还知道如何控制表单数组,所以下一个问题:我们如何为 formArray 提供值?
请记住,我们收到了一些喜欢,例如
{
businessName:'my business name'
authorized:['CULTIVATE', 'PROCESS']
}
当我们收到数据中的值时,我们可以使用一些类似
this.formGroupLicense.patchValue(
{
businessName:data.businessName,
authorized:this.authorized.map(x=>data.authorized.indexOf(x)>=0)
}
了解如何在 3 个元素的数组中使用 0、1、2 或 3 个元素转换“data.authorize”和数组,该数组取值为 true 或 false
好吧,我们需要做的最后一项工作是,在提交时,使用 formArray 的值(例如 [true,false,false] 来获取字符串数组
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]
和过滤器,只需要不为空的元素['CULTIVATE']
好吧,使用 pathValue 是可以的,但是为什么我们不创建一个函数来返回带有我们想要的数据的 formGroup
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)))
})
}
所以,当我们收到数据时,我们唯一需要的就是使用
this.formGroupLicense=this.createFormGroup(data)
第二种方法
我们有一个像
this.formGrowLicense=new FormGroup({
businessName:new FormControl(),
authorized:new FormControl()
})
是的!授权是一个存储数组的 FormControl。如果看到材质多勾选就是这种方法。为此,您可以使用自定义 formControl检查此SO 。让我解释一下(我不想要 customFormControl)
我们有一个辅助数组,其中包含两个属性“名称”和“值”,我们希望得到一些类似的属性,例如
authorizedAux: any = [{name:'CULTIVATE',value:true},
{name:'HARVEST',value:false},
{name:'PROCESS',value:true}]
所以我们添加一个函数
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
<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
推荐阅读
- flutter-layout - Flutter - 是否可以通过 Flutter PieChart 点击调用页面?
- scala - getPersistentRDDs 在 Spark 2.2.0 中返回缓存 RDD 和 DataFrame 的 Map,但在 Spark 2.4.7 中 - 它仅返回缓存 RDD 的 Map
- mysql - 当某一列的值出现时隐藏表中的行
- php - 在 phpmyadmin 中创建与 mysql 分离的用户
- kubernetes - 来自 Kubernetes 中副本集的单个工作 pod
- django - django is_active 不会禁用用户
- java - 如何在 Spring 中从不同的 Controller 调用 RestController 方法?
- ruby-on-rails - Rails:嵌套关联dosent设置user_id
- c++ - 如何将 char* 转换为长字符串以在 FindFirstFile 函数中使用它?
- firebase - 颤动的Firestore查询索引不起作用