我正在为我们的位置服务团队制作表单组件。此组件可以具有 city,state,county,country 和 zip 字段,具体取决于其配置方式。

我希望开发人员能够通过传入一个可以绑定到表单输入的每个字段的属性的单个位置对象来使用它,并且我还希望支持传入可以绑定到字段的 FormGroup。

我遇到的问题是每个字段的所有值都来自 API。我们想尽可能多地为用户提供 auto-populate 数据。

例如,当用户选择一个城市时,它应该填充州和国家,但清除县和邮政编码字段(城市可以是多个县或邮政编码),同时还填充相关的县和邮政编码选项列表所选城市的县和邮政编码。我不想进入业务逻辑,只是说每当表单值发生变化时,每个字段都有一组独特而复杂的规则。

使用ngModel方法,我在ngModelChange上推出了自己的商店 ala redux 和调度操作,以根据我们的业务规则更新整个位置对象。这非常有效。

当我在单独的FormControls上使用FormGroup尝试这样的事情时,我点击了调用堆栈限制,因为对其他字段的每次更改都会触发FormGroup上的updateAndValidate循环。我尝试patchValue而不是setValue并且我使用选项不emitEvent并将selfOnly设置为 true,但仍然达到了堆栈限制。

我的模板看起来像:

<my-input formControlName="city"
          (ngModelChange)="updateControls(
                             { type: 'CITY_CHANGE',
                               value: $event })">
</my-input>

然后在控制器中:

updateControls(action) {
  switch(action.type) {
    case "CITY_CHANGE":
      this.formgroup.controls.zip.setValue(undefined);
      this.formgroup.controls.county.setValue(undefined);
      this.formgroup.controls.city.setValue(action.value);
      this.formgroup.controls.state.setValue(// get state & set);
      this.formgroup.controls.country.setValue(//get country & set);
      break;
   case ... // you get the point
  }
}

正如我所说,我也用patchValue(val, { emitEvent: false, onlySelf: true }尝试了这个,但这对我没有帮助。我仍在达到调用堆栈限制。

我尝试在父 FormGroup 本身上订阅valueChanges,但它没有提供我更改的内容列表,只是表单的新状态。这是不可接受的,因为我需要知道改变了什么,以便我可以根据我的业务规则更新其他字段。

理想的情况是订阅表单并检查更改了哪个属性,然后根据我的业务规则更新表单的整个状态。除此之外,能够将 formControlName 单独绑定到输入,这样当我向 ngModelChange 注册时,它不会启动无限循环。

有没有人对我如何处理这个有任何想法或建议?我错过了一些明显的东西吗我想支持 FormGroup,因为我在一个拥有许多团队的大型企业项目中,我们希望我们的组件与他们的表单集成,无论他们使用哪种技术。