在自定义反应式表单控件上设置禁用会导致超出最大调用堆栈大小

Setting disabled on custom reactive form control results in Maximum call stack size exceeded

我在 Angular 项目中构建了一个自定义输入控件。一切正常,除非我将 disabled 属性设置为 true,然后在 setDisabledState 上发生一些无限循环导致

preview-4adb70f742b91f09679fb.js:1 ERROR RangeError: Maximum call stack size exceeded
    at eval (model.ts:1519)
    at eval (model.ts:1531)
    at eval (model.ts:1493)
    at Array.forEach (<anonymous>)
    at FormGroup._forEachChild (model.ts:1493)
    at FormGroup._reduceChildren (model.ts:1530)
    at FormGroup._reduceValue (model.ts:1518)
    at FormGroup._updateValue (model.ts:1505)
    at FormGroup.AbstractControl.updateValueAndValidity (model.ts:575)
    at FormControl.AbstractControl._updateAncestors (model.ts:533)

我创建了一个 Stackblitz 来展示问题:https://stackblitz.com/edit/angular-n34zrj

关于设置内部 FormControl 的禁用 属性(使用 diabled()、enabled()),我是否遗漏了什么?

如果是这样,请告诉我如何解决这个问题。把我的脑袋砸了几个小时。

在您的代码中,您通过根据布尔值 setDisabledState() 参数设置禁用状态来强制循环。在此方法中,您调用 disable() / enable() ,它们将自己调用 setDisabledState()。

  setDisabledState?(isDisabled: boolean): void {
    isDisabled ? this.control.disable() : this.control.enable();
  }

https://netbasal.com/angular-custom-form-controls-made-easy-4f963341c8e2

尝试像 Netanel Basal 那样做的事情:

  setDisabledState( isDisabled : boolean ) : void {
    const div = this.textarea.nativeElement;
    const action = isDisabled ? 'addClass' : 'removeClass';
    this.renderer[action](div, 'disabled');
  }

如果您在使用 Severin Klugs 中所述的答案时遇到错误,可以通过停止不必要的调用来修复,但在应用函数之前检查它们是否相同

setDisabledState?(isDisabled: boolean): void {
    if(isDisabled == this.control.disabled) return;
    isDisabled ? this.control.disable() : this.control.enable();
}