angular - 将 formControlName 用于 react 形式的自定义输入组件

标签 angular angular-reactive-forms angular-forms angular-validation

有一个自定义输入组件,它以带有验证的 react 形式使用:

@Component({
    moduleId: module.id.toString(),
    selector: 'custom-select',
    templateUrl: 'custom-select.component.html',
    styleUrls: ['custom-select.component.css']
})
export class CustomSelectComponent {
    @Input() public items: SelectModel[];
    public model: SelectModel;
    constructor(private customSelectService: CustomSelectService) {
        this.customSelectService.Selected.subscribe((data: SelectModel) => {
            this.model = data;
        });
    }
    public newSelect(select: SelectModel): void {
        this.customSelectService.updateSelected(select);
    }
}

效果很好,我正在使用 custom-select以 react 形式并希望像下面这样验证它:

<custom-select id="country" [items]="selectItems" formControlName="country"></custom-select>
<div *ngIf=" myFrom.controls['country'].invalid && (myFrom.controls['country'].dirty 
             || myFrom.controls['country'].touched) " class="ha-control-alert">
    <div *ngIf="myFrom.controls['country'].hasError('required')">Country is required</div>
</div>

这就是我在组件中声明表单的方式

this.myFrom = this.formBuilder.group({
    country: [null, Validators.required],
})

但是当我添加 formControlName对于验证,它会出现错误,显示 名称为“国家”的表单控件没有值访问器 .我该如何处理?

最佳答案

脚步

  • 在装饰器中添加 NG_VALUE_ACCESSOR 的提供程序
  • 在类
  • 中实现 ControlValueAccessor
  • 像这样创建 onChange 函数 onChange = (value: boolean) => {};
  • 添加ControlValueAccessor接口(interface)的registerOnChange、writeValue和registerOnTouched方法
  • 在将要更改 select 值的方法中,调用作为参数传递 select 值的 onChange 函数。

  •         import ...
            import { Component, forwardRef } from '@angular/core';
            import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
            
        
            @Component({
                moduleId: module.id.toString(),
                selector: 'custom-select',
                templateUrl: 'custom-select.component.html',
                styleUrls: ['custom-select.component.css'],
                // STEP 1
                providers: [{
                  provide: NG_VALUE_ACCESSOR,
                  multi: true,
                  useExisting: forwardRef(() => CustomSelectComponent)
                }]
            })
            // STEP 2
            export class CustomSelectComponent implements ControlValueAccessor {
                // STEP 3
                onChange = (value: SelectModel) => {};
                @Input() public items: SelectModel[];
                public model: SelectModel;
                constructor(private customSelectService: CustomSelectService) {
                    this.customSelectService.Selected.subscribe((data: SelectModel) => {
                        this.model = data;
                    });
                }
                public newSelect(select: SelectModel): void {
                    // STEP 5
                    this.onChange(select);
                    this.customSelectService.updateSelected(select);
                }
                // STEP 4
                registerOnChange(fn: (value: SelectModel) => void): void {
                    this.onChange = fn;
                }
                writeValue() {}
                registerOnTouched(){}
            }
    
    不要忘记在选择器中添加 formControlName。

    关于angular - 将 formControlName 用于 react 形式的自定义输入组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46141714/

    相关文章:

    Angular 5 react 形式 - 禁用单选组中的一个单选选项

    angular - 如何创建嵌套的表单组,基于模型的 react 表单

    javascript - 如何在应用程序中为 Angular Forms 制作带有表单控件输入的通用组件

    javascript - 从不同的表单组更新表单组表单控件值,但我不想永久更改值(Angular)

    javascript - 如何使用highcharts显示多个饼图

    javascript - 刷新后,firebase Auth当前用户返回null

    javascript - 根据其他单元格在表格中显示按钮

    angular - "this"不能用于 typescript 函数 (Angular)

    angular - 大于 Angular Validator 中的跨域验证

    angular - 订阅 Angular react 形式的输入错误