【问题标题】:Angular: Custom FormControl doesn't update view after FormGroup.reset()Angular:自定义 FormControl 在 FormGroup.reset() 之后不更新视图
【发布时间】:2019-09-18 21:11:14
【问题描述】:

这是我的“注册”页面:

  • 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

【问题讨论】:

  • 问题很老,但您找到解决方案了吗?

标签: angular


【解决方案1】:

mat-select 中添加value 属性。

<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

【讨论】:

  • 我已经考虑过了。我用谷歌搜索了一下,发现有几个来源认为双向绑定在这种情况下不是一种好的做法……更糟糕的是 - 这样它就不会显示验证错误。应该使用writeWalue方法,就是不知道怎么...
猜你喜欢
  • 2021-10-08
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多