如何根据对其他 formControl 值所做的更改更新一个 formControl 的值?
How to update value of one formControl based on the changes made in other formControl values?
我在 angular 中使用三个可编辑的表单控件制作了一个反应式表单。
HTML代码:
<table class="table-details">
<tr>
<th>ID</th>
<th>Name</th>
<th>Carbohydrates</th>
<th>Fats</th>
<th>Protein</th>
<th>Calories</th>
<th style="padding-left: 4rem">Status</th>
<th>Action</th>
</tr>
<tr *ngFor="let food of foods; index as index">
<td>{{ food.id }}</td>
<td>
<editable class="name" (update)="updateField(index, 'name')">
<ng-template appViewMode>
{{food.name}}
<mat-icon>edit</mat-icon>
</ng-template>
<ng-template appEditMode>
<input [formControl]="getControl(index, 'name')" focusable>
</ng-template>
</editable>
</td>
<td>
<editable class="carbohydrates" (update)="updateField(index, 'carbohydrates')">
<ng-template appViewMode>
{{food.carbohydrates}} gms
<mat-icon>edit</mat-icon>
</ng-template>
<ng-template appEditMode>
<input [formControl]="getControl(index, 'carbohydrates')" focusable>
</ng-template>
</editable>
</td>
<td>
<editable class="fats" (update)="updateField(index, 'fats')">
<ng-template appViewMode>
{{food.fats}} gms
<mat-icon>edit</mat-icon>
</ng-template>
<ng-template appEditMode>
<input [formControl]="getControl(index, 'fats')" focusable>
</ng-template>
</editable>
</td>
<td>
<editable class="protein" (update)="updateField(index, 'protein')">
<ng-template appViewMode>
{{food.protein}}gms
<mat-icon>edit</mat-icon>
</ng-template>
<ng-template appEditMode>
<input [formControl]="getControl(index, 'protein')" focusable>
</ng-template>
</editable>
</td>
<td>
<div>
<p [formControl]="getCalories()">
{{food.calories}} kcals
</p>
</div>
</td>
<td>
<div class="boolean">
<mat-icon>lens</mat-icon>
Active
</div>
</td>
<td>
<div class="actions">
<mat-icon>delete</mat-icon>
</div>
</td>
</tr>
</table>
这是ts代码:
export class FoodDetailsComponent implements OnInit {
items!: FormArray
foods:any = FOODDATAS;
constructor(private fb : FormBuilder) {}
ngOnInit(): void {
const toGroup = this.foods.map((food:any) => {
return new FormGroup({
name: new FormControl(food.name,[
Validators.required,
Validators.pattern(/^[a-zA-Z]*$/)
]),
carbohydrates: new FormControl(food.carbohydrates, [
Validators.required,
Validators.pattern(/^\d+(\.\d{1,2})?$/)
]),
fats: new FormControl(food.fats, [
Validators.required,
Validators.pattern(/^\d+(\.\d{1,2})?$/)
]),
protein: new FormControl(food.protein, [
Validators.required,
Validators.pattern(/^\d+(\.\d{1,2})?$/)
]),
calories: new FormControl(food.calories, [
Validators.required
])
});
});
this.items = new FormArray(toGroup)
}
getCalories() : FormControl {
const carbs:any = this.items.get('carbohydrates.2.inArray')
const protein:any = this.items.get('protein.3.inArray')
const fats:any = this.items.get('fats.2.inArray')
return ((carbs * 4) + (protein * 4) + (fats * 9)) as unknown as FormControl
}
getControl(index: number, field: string): FormControl {
return this.items.at(index).get(field) as FormControl;
}
updateField(index: number, field: string) {
const control = this.getControl(index, field);
if (control.valid) {
this.foods = this.foods.map((e: any, i: number) => {
if (index === i) {
return {
...e,
[field]: control.value
};
}
return e;
});
}
}
'calories'的值,我想根据'carbohydrates'、'protein'和'fats'的值自动计算,使用这个逻辑
function getCalories(carbs:Double, protein:Double, fat:Double) {
return carbs x 4 + protein x 4 + fats x 9
}
我想让它监控其他三个formControl值的变化。我尝试使用 valueChanges
但它无法与 fromArray 一起使用。(P.S-如何访问 fromArray 的值?)
提前致谢
ValueChanges 不起作用,因为您没有使用父表单组指令包装表单数组指令。此外,我建议不要使用这么多模板函数,这是一种通过让 formarray 为您处理来访问控件的更简单方法,如下例
<!-- below is what you are missing, a parent form group-->
<table [formGroup]="formGroup">
<tbody formArrayName="items">
<tr
*ngFor="let item of formGroup.get('items').controls; let i = index;">
<td [formGroupName]="i">
<input formControlName="carbohydrates" placeholder="Item name">
</td>
</tr>
</tbody>
</table>
我在 angular 中使用三个可编辑的表单控件制作了一个反应式表单。 HTML代码:
<table class="table-details">
<tr>
<th>ID</th>
<th>Name</th>
<th>Carbohydrates</th>
<th>Fats</th>
<th>Protein</th>
<th>Calories</th>
<th style="padding-left: 4rem">Status</th>
<th>Action</th>
</tr>
<tr *ngFor="let food of foods; index as index">
<td>{{ food.id }}</td>
<td>
<editable class="name" (update)="updateField(index, 'name')">
<ng-template appViewMode>
{{food.name}}
<mat-icon>edit</mat-icon>
</ng-template>
<ng-template appEditMode>
<input [formControl]="getControl(index, 'name')" focusable>
</ng-template>
</editable>
</td>
<td>
<editable class="carbohydrates" (update)="updateField(index, 'carbohydrates')">
<ng-template appViewMode>
{{food.carbohydrates}} gms
<mat-icon>edit</mat-icon>
</ng-template>
<ng-template appEditMode>
<input [formControl]="getControl(index, 'carbohydrates')" focusable>
</ng-template>
</editable>
</td>
<td>
<editable class="fats" (update)="updateField(index, 'fats')">
<ng-template appViewMode>
{{food.fats}} gms
<mat-icon>edit</mat-icon>
</ng-template>
<ng-template appEditMode>
<input [formControl]="getControl(index, 'fats')" focusable>
</ng-template>
</editable>
</td>
<td>
<editable class="protein" (update)="updateField(index, 'protein')">
<ng-template appViewMode>
{{food.protein}}gms
<mat-icon>edit</mat-icon>
</ng-template>
<ng-template appEditMode>
<input [formControl]="getControl(index, 'protein')" focusable>
</ng-template>
</editable>
</td>
<td>
<div>
<p [formControl]="getCalories()">
{{food.calories}} kcals
</p>
</div>
</td>
<td>
<div class="boolean">
<mat-icon>lens</mat-icon>
Active
</div>
</td>
<td>
<div class="actions">
<mat-icon>delete</mat-icon>
</div>
</td>
</tr>
</table>
这是ts代码:
export class FoodDetailsComponent implements OnInit {
items!: FormArray
foods:any = FOODDATAS;
constructor(private fb : FormBuilder) {}
ngOnInit(): void {
const toGroup = this.foods.map((food:any) => {
return new FormGroup({
name: new FormControl(food.name,[
Validators.required,
Validators.pattern(/^[a-zA-Z]*$/)
]),
carbohydrates: new FormControl(food.carbohydrates, [
Validators.required,
Validators.pattern(/^\d+(\.\d{1,2})?$/)
]),
fats: new FormControl(food.fats, [
Validators.required,
Validators.pattern(/^\d+(\.\d{1,2})?$/)
]),
protein: new FormControl(food.protein, [
Validators.required,
Validators.pattern(/^\d+(\.\d{1,2})?$/)
]),
calories: new FormControl(food.calories, [
Validators.required
])
});
});
this.items = new FormArray(toGroup)
}
getCalories() : FormControl {
const carbs:any = this.items.get('carbohydrates.2.inArray')
const protein:any = this.items.get('protein.3.inArray')
const fats:any = this.items.get('fats.2.inArray')
return ((carbs * 4) + (protein * 4) + (fats * 9)) as unknown as FormControl
}
getControl(index: number, field: string): FormControl {
return this.items.at(index).get(field) as FormControl;
}
updateField(index: number, field: string) {
const control = this.getControl(index, field);
if (control.valid) {
this.foods = this.foods.map((e: any, i: number) => {
if (index === i) {
return {
...e,
[field]: control.value
};
}
return e;
});
}
}
'calories'的值,我想根据'carbohydrates'、'protein'和'fats'的值自动计算,使用这个逻辑
function getCalories(carbs:Double, protein:Double, fat:Double) {
return carbs x 4 + protein x 4 + fats x 9
}
我想让它监控其他三个formControl值的变化。我尝试使用 valueChanges
但它无法与 fromArray 一起使用。(P.S-如何访问 fromArray 的值?)
提前致谢
ValueChanges 不起作用,因为您没有使用父表单组指令包装表单数组指令。此外,我建议不要使用这么多模板函数,这是一种通过让 formarray 为您处理来访问控件的更简单方法,如下例
<!-- below is what you are missing, a parent form group-->
<table [formGroup]="formGroup">
<tbody formArrayName="items">
<tr
*ngFor="let item of formGroup.get('items').controls; let i = index;">
<td [formGroupName]="i">
<input formControlName="carbohydrates" placeholder="Item name">
</td>
</tr>
</tbody>
</table>