javascript - Angular 组件作为 self 验证的 formControls

标签 javascript angular forms angular-reactive-forms

我不确定是否有更好的方法来执行此操作,我认为应该有。基本上我有一个组件,我想将其视为独立的表单控件。此控件将始终附加某种特殊验证,我希望它在使用该组件时冒泡到表单。

我附上了 plunker .如果组件/formControl 无效,是否有办法将表单标记为无效?我知道我可以将验证器添加到表单本身,但我想让事情变得简单且更可预测,以便将来使用此组件。我也愿意接受更好的想法。

@Component({
  selector: 'my-app',
  template: `
    <form [formGroup]="form">
      <my-component-control formControlName="myComponent"></my-component-control>
    </form>
    <div>Form Value: {{form.value | json}}</div>
    <div>Form Valid: {{form.valid}}</div>
  `,
})
export class App {
  constructor(fb: FormBuilder) {
    this.form = fb.group({
      myComponent: ''
    });
  }
}

@Component({
  selector: 'my-component-control',
  template: `
    <div>Control Errors: {{control.errors | json}}</div>
    <input [formControl]="control">
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi: true,
      useExisting: forwardRef(() => MyComponentComponent),
    }
  ]
})
export class MyComponentComponent implements ControlValueAccessor {
  control: FormControl;

  onChange: any = () => { };
  onTouched: any = () => { };

  constructor() {
    this.control = new FormControl('', (control) => {
      return control.value ? null : {shouldHaveSomething: true};
    });
    this.control.valueChanges.subscribe((value) => {
      this.onChange(value);
      this.onTouched();
    });
  }

  writeValue (obj: any): void {
    this.control.setValue(obj);
  }
  registerOnChange (fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched (fn: any): void {
    this.onTouched = fn;
  }
  setDisabledState?(isDisabled: boolean): void {
    throw new Error('Method not implemented.');
  }
}

最佳答案

一个解决方案可能是使用 setValidators主机 AbstractControl

上的方法

为此,我将通过 NgControl 获取对 AbstractControl 的引用。我们不能只在构造函数中注入(inject) NgControl,因为我们会遇到实例化循环依赖的问题。

constructor(private injector: Injector) {
  ...     
}

ngOnInit() {
  Promise.resolve().then(() => {
    const hostControl = this.injector.get(NgControl, null);
    if (hostControl) {
      hostControl.control.setValidators(this.control.validator);
      hostControl.control.updateValueAndValidity();
    }
  }); 
}

Ng-run Example

关于javascript - Angular 组件作为 self 验证的 formControls,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49199723/

相关文章:

javascript - 如何在 AVA 上使用 @decorator (redux-connect) 测试组件 undecorator?

.net - "Microsoft JScript compilation error: Expected ' ; '"调用ASMX Web服务

javascript - 带有关联的 Sequelize.build

Angular Http Client - 如何将嵌套参数对象传递给 GET API

javascript - Dojo表单获取值

javascript - 单选按钮行 JavaScript

angular - 对象可能为 Null

Angular - 响应式(Reactive)表单 - FormGroupName 里面的 FormGroupName

javascript - 如何更改输入的值以便在提交时传递?

PHP/HTML 表单提交