【问题标题】:Validation is not propagate to Custom Form Control ng-select in Angular验证不会传播到 Angular 中的自定义表单控件 ng-select
【发布时间】:2020-06-12 23:43:55
【问题描述】:

我在 Angular 9 应用程序中使用带有自定义表单控件的反应式表单。

我用自定义表单控件包装了我的 ng-select 控件。

我的验证有问题。我将 formControl 设置为必需。 Documentation says ng-invalid css 类应该自动设置为 ng-select。但实际上使用自定义表单控件它不能正常工作。未设置 css 类,但设置了包装器类。我做错了什么还是这是图书馆的问题?

检查堆栈闪电战: https://stackblitz.com/edit/angular-rmvttg-ex63ka?file=src/forms-single-select-example.component.html&fbclid=IwAR2robtd_15khTVhmW59lLhn21HOHl_yYTrCWKaPRmfUt1QVvUn3n8V4Vjo

【问题讨论】:

    标签: angular typescript angular-reactive-forms angular-ngselect


    【解决方案1】:

    DiPix,问题在于 Angular 将控件状态 CSS 类添加到您的自定义控件,而不是属于您的内部控件的 ng-select

    您可以注入 ngControl 并检查 control.control.invalid 和 control.control.touched

    constructor(private injector:Injector){}
    ngOnInit()
    {
       this.control = this.injector.get(NgControl);
    }
    

    然后你可以使用一些类似的

      <ng-select #mySelect  [ngClass]="{'ng-invalid':control?.control.invalid,
                                        'ng-touched':control?.control.touched}"
       ....>
    

    另一种方法是询问父母的班级。所以如果你定义了一个像

    这样的getter
    get parentClass()
    {
      const match = /class=\"(.*?)\">/.exec(this.element.nativeElement.parentElement.innerHTML);
      return match[0].split('"')[1]
    }
    
    constructor(private element:ElementRef){}
    

    你可以使用

    <ng-select #mySelect  [ngClass]="parentClass" 
      ...>
    

    你可以在your forked stackblitz看到

    注意:无论如何,为了包装一个 ng-select,创建一个自定义表单控件是不必要的,只是一个带有 @Input 的 简单组件

    @Input()control:any
    

    你使用 as

        <mycontrol [control]="someForm.get('someControl')"></mycontrol>
    

    你可以看到this another stackblitz变得多么简单

    【讨论】:

    • 那么基本上什么时候应该使用自定义表单控件?
    • 在我看来,如果向控件添加新的外观,自定义表单控件很有用。 datePicker 是“自定义表单控件”的一个很好的例子,多选是另一个很好的例子,或者一个仪表,或者一个在下拉时显示表格的组合,(我怀疑带有掩码的输入)或...... . 如果只想“分组”输入,例如询问号码、到期日期和 CVC 的信用卡-即使显示卡类型-或带有街道、城市、国家和 CP 的一组地址,我更喜欢使用组件。但实际上这只是个人意见。我只是 Angular 的业余爱好者
    • 对我有意义。但我有一个小问题。我已经指示寻找formControlName 属性this.hostElement.nativeElement.nextElementSibling.attributes.formControlName 现在这样的元素不存在,因为我正在使用未在DOM 上显示的[control]。知道如何获得 controlName 吗?
    【解决方案2】:

    您可以通过InputFormGroup 向下传递到您的子组件并将其设置为ng-select 来解决此问题:

    <mycontrol formControlName="someControl" [parentFormGroup]="someForm" ></mycontrol>
    

    组件:

    export class MyControlComponent implements ControlValueAccessor {
    
      @Input() parentFormGroup: FormGroup;
    ...
    

    模板:

    <ng-select #mySelect
               [formGroup]="parentFormGroup"
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2022-08-19
      • 1970-01-01
      相关资源
      最近更新 更多