FormGroup.value returns 默认值不是更新后的值

FormGroup.value returns the default value not the updated ones

我有一个小表单,单击一个按钮我想访问该表单的最新值。但是我得到的是我初始化表单时使用的默认值。

我正在使用 material 设计输入字段

component.ts

import { Component, EventEmitter, Inject, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ElementService } from 'src/app/services/element.service';

import { PeriodicElement } from '../../../Interfaces/periodicElement';

@Component({
    selector: 'app-create',
    templateUrl: './create.component.html',
    styleUrls: ['./create.component.css']
})

export class CreateComponent {

    formGroup: FormGroup;
    inProgress: boolean = false;
    onChange = (_: any) => { };

    constructor(
        private elementService: ElementService,
        private formBuilder: FormBuilder,
        public dialogRef: MatDialogRef<CreateComponent>,
        @Inject(MAT_DIALOG_DATA) public data: PeriodicElement
    ) {
        this.formGroup = this.formBuilder.group({
            position: [this.data.position, Validators.required],
            name: [this.data.name, Validators.required],
            weight: [this.data.weight, Validators.required],
            symbol: [this.data.symbol, Validators.required]
        });
    }

    valueChanges(controlGroup: string) {
        let value = this.formGroup.get(controlGroup)?.value;
        this.onChange(value);
    }

    save() {
        console.log(this.formGroup.value)
        this.inProgress = true;
        this.elementService.list().subscribe(list => {
            this.inProgress = false;
            this.dialogRef.close(list);
        });

    }
}

Component.html

<h1 mat-dialog-title>Add Element</h1>
<mat-dialog-content>
    <form [formGroup]="formGroup">
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Position</mat-label>
            <input matInput type="number" [value]="data.position" (valueChanges)="valueChanges('position')" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Name</mat-label>
            <input matInput [value]="data.name" (valueChanges)="valueChanges('name')" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Weight</mat-label>
            <input matInput type="number" [value]="data.weight" step=".00001" (valueChanges)="valueChanges('weight')" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Symbol</mat-label>
            <input matInput [value]="data.symbol" (valueChanges)="valueChanges('symbol')" />
        </mat-form-field>
    </form>
</mat-dialog-content>
<mat-dialog-actions align=end>
    <mat-spinner [diameter]="20" *ngIf="inProgress"></mat-spinner>
    <button color="accent" mat-raised-button (click)="save()">Add</button>
    <button color="warn" mat-raised-button mat-dialog-close>Cancel</button>
</mat-dialog-actions>

修改component.html为-

<h1 mat-dialog-title>Add Element</h1>
<mat-dialog-content>
    <form [formGroup]="formGroup">
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Position</mat-label>
            <input matInput type="number" formControlName="position" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Name</mat-label>
            <input matInput formControlName="name" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Weight</mat-label>
            <input matInput type="number" step=".00001" formControlName="weight" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Symbol</mat-label>
            <input matInput formControlName="symbol" />
        </mat-form-field>
    </form>
</mat-dialog-content>
<mat-dialog-actions align=end>
    <button color="accent" mat-raised-button (click)="save()">Add</button>
    <button color="warn" mat-raised-button mat-dialog-close>Cancel</button>
</mat-dialog-actions>

并且您不再需要 onChange 属性 和 component.ts 中的 valueChanges() 方法。

您的模板代码被 (valueChanges)="valueChanges('field')" 污染了。只需将其从模板中删除并使用 Reactive Forms 功能即可。使用 formControlName 作为您的输入,如@atiyar 所说 (formControlName="YourFieldName").

formform control 的新值可以使用它的 valueChanges 方法在您的控制器中捕获。

ngOnInit(): void {
  this.formGroup.valueChanges
     .pipe(distinctUntilChanged()) // used to be fired only for value changed
     .subscribe(value => {
        // value = all form fields
        // do something
     });
}

这就是全部。干净整洁。

您没有正确使用 formGroup。缺少表单元素的 formControlName 属性

HTML

    <h1 mat-dialog-title>Add Element</h1>
    <mat-dialog-content>
        <form [formGroup]="myForm">
            <mat-form-field appearance="fill" class="spacer">
                <mat-label>Position</mat-label>
                <input matInput type="number" name="position" formControlName="position" />
            </mat-form-field>
            <mat-form-field appearance="fill" class="spacer">
                <mat-label>Name</mat-label>
                <input matInput name="name" formControlName="name" />
            </mat-form-field>
            <mat-form-field appearance="fill" class="spacer">
                <mat-label>Weight</mat-label>
                <input matInput type="number" name="weight" step=".00001" formControlName="weight" />
            </mat-form-field>
            <mat-form-field appearance="fill" class="spacer">
                <mat-label>Symbol</mat-label>
                <input matInput name="symbol" formControlName="symbol" />
            </mat-form-field>
        </form>
    </mat-dialog-content>
    <mat-dialog-actions align=end>
        <mat-spinner [diameter]="20" *ngIf="inProgress"></mat-spinner>
        <button color="accent" mat-raised-button (click)="save()">Add</button>
        <button color="warn" mat-raised-button mat-dialog-close>Cancel</button>
    </mat-dialog-actions>

TS


    public myForm: FormGroup;

    constructor(
        private elementService: ElementService,
        private formBuilder: FormBuilder,
        public dialogRef: MatDialogRef<CreateComponent>,
        @Inject(MAT_DIALOG_DATA) public data: PeriodicElement
    ) {
        this.myForm = this.formBuilder.group({
            position: [this.data.position, Validators.required],
            name: [this.data.name, Validators.required],
            weight: [this.data.weight, Validators.required],
            symbol: [this.data.symbol, Validators.required]
        });

        // listener for value change
        this.myForm.valueChanges.subscribe((data) => {
            console.log('onChange ===> ', data);
        });
    }

    save() {
        console.log('myForm ===> ', this.myForm);
        if (this.myForm.valid) {
            // api call to server or whatever you want to do with it
        }
    }