角度:自定义FormControl不会在FormGroup.reset()之后更新视图

时间:2019-09-18 12:29:43

标签: angular

这是我的“注册”页面:

  • registration.component.html

    <mat-form-field appearance="standard">
        <mat-label>First name</mat-label>
        <input matInput formControlName="firstName">
    </mat-form-field>
    
    <div formGroupName="locationGroup"
           class="location-group">
    
        <acme-location-picker formControlName="country"
                            [label]="'Country'"
                            [locations]="countries"></acme-location-picker>
    
        <acme-location-picker formControlName="city"
                            [label]="'City'"
                            [locations]="cities"></acme-location-picker>
    
    </div>
    
  • registration.component.ts     this.registrationForm = this.fb.group({

        firstName: ['', Validators.compose([Validators.required])],
    
        locationGroup: this.fb.group({
            country: [null, Validators.compose([Validators.required])],
            city: [null, Validators.compose([Validators.required])],
        }),
    
    });
    
    public onRegistrationFormSubmit(): void {
        this.registrationForm.reset({ onlySelf: false });
    }
    
    public showValues(): void {
        console.log('values: ', this.registrationForm.value);
    }
    

我的自定义“位置选择器”

  • location-picker.component.html

    <mat-form-field appearance="standard">
        <mat-label>{{label}}</mat-label>
        <mat-select [disabled]="disabled"
          (selectionChange)="onChange($event.value)">
            <mat-option [value]="null">...</mat-option>
            <mat-option *ngFor="let location of locations"
                [value]="location.code">
                {{location.name}} ({{location.code}})
            </mat-option>
        </mat-select>
    </mat-form-field>
    
  • location-picker.component.ts

    @Component({
        ...
        providers: [{
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => LocationPickerComponent),
            multi: true }]
    })
    export class LocationPickerComponent implements ControlValueAccessor {
        @Input() public label: string;
        @Input() public locations: string[];
    
        selectedOption: string;
        disabled: boolean;
        onChange = (val: any) => { };
        onTouched = () => { };
    
        writeValue(val: string): void {
            console.log('writeValue:', val);
            this.selectedOption = val ? val : null;
        }
        setDisabledState?(isDisabled: boolean): void {
            this.disabled = isDisabled;
        }          
        registerOnChange(fn: () => void): void {
            this.onChange = fn;
        }
        registerOnTouched(fn: () => void): void {
            this.onTouched = fn;
        }
    }
    

onRegistrationFormSubmit()方法有效地重置了整个表单。
使用showValues()检查表单的模型后,可以看到locationGroup的所有字段均为空。
但是,尽管事实是调用了writeValue方法,但我的自定义位置选择器的UI不会更新(不显示三个点)。
除了我自定义的formControl字段(“国家/地区”和“城市选择”)外,该表单的所有其他字段均重置为各自的值。


这是Stackblitz example

1 个答案:

答案 0 :(得分:0)

value中添加mat-select属性。

<mat-form-field appearance="standard">
    <mat-label>{{label}}</mat-label>
    <mat-select
      [disabled]="disabled"
      [(value)]="selectedOption"
      (selectionChange)="onChange($event.value)">
        <mat-option [value]="null">...</mat-option>
        <mat-option
        *ngFor="let location of locations"
        [value]="location.code">
        {{location.name}} ({{location.code}})
        </mat-option>
    </mat-select>
</mat-form-field>

https://stackblitz.com/edit/custom-formcontrol-update-demms9?file=src/app/location-picker/location-picker.component.html