繁体   English   中英

Angular ControlValueAccessor如何转移无效状态?

[英]Angular ControlValueAccessor how to transfert the invalid status?

我已经使用ControlValueAccessor创建了一个自定义输入,我可以在 formControl 中使用它并且它工作正常。 现在我想知道表单控件何时被认为无效,无法在我的自定义组件内的输入上显示红色边框。

这是我的自定义输入:

@Component({
  selector: 'app-input',
  templateUrl: './input.component.html',
  styleUrls: ['./input.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi: true,
      useExisting: InputComponent,
    },
  ],
})
export class InputComponent implements ControlValueAccessor {
  group = new FormGroup({
    input: new FormControl(''),
  });
  touched: boolean = false;

  // The id used for the html
  id!: number;

  // The label of the html input
  @Input() label: string = '';
  @Input() type: string = 'text';

  // The method called when the input is touched
  onTouched = () => {};

  constructor() {
    this.id = Math.floor(Math.random() * 100);
  }
  /**
   * The setter of the input value
   * @param value
   */
  writeValue(value: string): void {
    this.input.setValue(value);
  }

  /**
   * Function to subscribe to changes
   * @param fn
   */
  registerOnChange(fn: any): void {
    this.input.valueChanges.subscribe((value) => {
      fn(value);
    });
  }
  /**
   * Function to subscribe when the input is touched
   * @param fn
   */
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  /**
   * fucntion called to define the input as touched
   */
  markAsTouched() {
    if (!this.touched) {
      this.onTouched();
      this.touched = true;
    }
  }

  /**
   *
   * @param isDisabled
   */
  setDisabledState?(isDisabled: boolean): void {
    if (isDisabled) {
      this.input.disable();
    } else {
      this.input.enable();
    }
  }

  get input() {
    return this.group.get('input') as FormControl;
  }
}

然后我可以这样使用它。

<app-input
  formControlName="email"
  label="Email"
></app-input>

如果我的 email 表单控件无效(例如,因为它不是有效的 email),那么在我的 DOM 组件上添加了一些 class。 在此处输入图像描述

有没有办法在 TS 组件中获取有效性状态?

不要在装饰器中使用providers属性提供值访问器,而是使用以下命令:

constructor(
  @Optional() @Self() private ngControl: NgControl
) {
  // ...
  if (this.ngControl) this.ngControl.valueAccessor = this;
}

它做同样的事情。 但在您的情况下,它所做的更多是让您使用this.ngControl.control访问本机表单控件。

这意味着您可以在任何给定点获取控件的状态,例如,您可以这样做:

get status() {
  return this.ngControl.control.status; // "INVALID", "VALID", "PENDING"
}

你可以像这样注入Injector

export class InputComponent implements OnInit , ControlValueAccessor {

  _control!: NgControl;

  constructor(@Inject(INJECTOR) private injector: Injector) { }

  ngOnInit(): void {
    this._control = this.injector.get(NgControl);
}

然后您可以访问所有控制方法 - 例如:

  get isError() {
    return this._control.control?.invalid;
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM