You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Zero Angular中Form.io Choices.js下拉框初始不显示选中值问题

问题描述
  • 基于ASP.NET Zero的Angular项目中,使用Form.io实现多标签向导表单,存在跨标签的相同下拉框字段treatmentStageId
  • 该字段通过异步接口从后端加载选项,模型中已存在选中值(如treatmentStageId = 2),但下拉框初始显示为空,点击后才会展示正确选中值
  • 观察到的行为:
    • 下拉框选项异步加载
    • 表单在选项加载完成前已渲染
    • 选项加载完成后Form.io未自动重新绑定值
    • 点击下拉框触发内部刷新后,选中值正常显示
相关代码

字段Schema

{
  "label": "Treatment Stage",
  "widget": "choicesjs",
  "dataSrc": "custom",
  "data": {
    "custom": "values = angularComponent.treatmentStagesValues"
  },
  "valueProperty": "TreatmentStageId",
  "template": "{{ item.text }}",
  "key": "yporAssessment.treatmentStageId",
  "type": "select",
  "lazyLoad": false
}

数据加载函数

async getTreatmentStagesValues() {
    return this._treatmentStage.get(...).toPromise().then(data => {
        this.treatmentStagesValues = data.map(x => ({
            text: x.text,
            TreatmentStageId: x.id
        }));
        return this.treatmentStagesValues;
    });
}

向导数据绑定代码

this._yporAssessment.getWizardData(...).subscribe(async (wizardFormData) => {

    const values = await this._commonDynamicWizard.getTreatmentStagesValues();
    this._commonDynamicWizard.treatmentStagesValues = values;

    const dataWrapper: any = {};
    dataWrapper.data = JSON.parse(JSON.stringify(wizardFormData));

    this.nebulaWizardData = JSON.parse(JSON.stringify(dataWrapper));
});
已尝试方案
  • 在渲染表单前使用await等待数据加载
  • 将Schema中的数据源从函数改为数组
  • 设置lazyLoad: false
  • 使用setTimeout结合setsubmission()方法
  • 确保跨标签的字段key一致
解决方案

1. 同步异步数据与Form.io渲染流程

核心是确保表单初始化/数据绑定操作在异步数据加载完成后执行:

  • 改用RxJS的forkJoin合并多个异步请求(向导数据+下拉选项),等所有数据就绪后再初始化表单:
    forkJoin([
      this._yporAssessment.getWizardData(...),
      this._commonDynamicWizard.getTreatmentStagesValues()
    ]).subscribe(([wizardFormData, treatmentValues]) => {
      this._commonDynamicWizard.treatmentStagesValues = treatmentValues;
      const dataWrapper = { data: JSON.parse(JSON.stringify(wizardFormData)) };
      this.nebulaWizardData = JSON.parse(JSON.stringify(dataWrapper));
      // 此处触发表单渲染逻辑(如果之前是自动渲染,确保此时数据已就绪)
    });
    
  • 若表单已提前渲染,需在数据加载完成后手动触发表单数据同步。

2. 无需用户交互强制重新绑定下拉框值

通过Form.io表单实例的API主动刷新字段或整个表单:

  • 先在组件中声明Form.io实例:@ViewChild(FormioComponent) formioComponent!: FormioComponent;
  • 数据加载完成后执行:
    // 刷新单个目标字段
    const field = this.formioComponent.form.getComponent('yporAssessment.treatmentStageId');
    if (field) {
      field.refresh(); // 强制字段重新渲染选项并绑定值
    }
    
    // 或刷新整个表单(适合多字段同步场景)
    this.formioComponent.form.refresh();
    
  • 也可通过重新设置submission触发绑定:
    this.formioComponent.setSubmission(this.nebulaWizardData);
    

3. Angular中优雅处理(避免setTimeout)

  • 用RxJS管理异步流:避免async/await嵌套,通过switchMap等操作符串联请求,确保数据顺序和就绪状态:
    this._yporAssessment.getWizardData(...)
      .pipe(
        switchMap(wizardFormData => 
          this._commonDynamicWizard.getTreatmentStagesValues().pipe(
            map(treatmentValues => ({ wizardFormData, treatmentValues }))
          )
        )
      )
      .subscribe(({ wizardFormData, treatmentValues }) => {
        this._commonDynamicWizard.treatmentStagesValues = treatmentValues;
        const dataWrapper = { data: JSON.parse(JSON.stringify(wizardFormData)) };
        this.nebulaWizardData = JSON.parse(JSON.stringify(dataWrapper));
        // 触发Angular变更检测,确保数据同步到视图
        this.cdr.detectChanges();
      });
    
  • 手动触发Angular变更检测:注入ChangeDetectorRef,在数据更新后调用cdr.detectChanges(),确保Angular将数据变化同步到视图,让Form.io感知到数据源更新。
  • 用BehaviorSubject包装数据源:将treatmentStagesValues改为BehaviorSubject<any[]>,实现数据源更新时自动同步到Formio:
    // 组件中定义
    treatmentStagesValues$ = new BehaviorSubject<any[]>([]);
    
    async getTreatmentStagesValues() {
      const data = await this._treatmentStage.get(...).toPromise();
      const values = data.map(x => ({ text: x.text, TreatmentStageId: x.id }));
      this.treatmentStagesValues$.next(values);
      return values;
    }
    
    // Schema中修改data.custom
    "custom": "values = angularComponent.treatmentStagesValues$.value"
    

内容的提问来源于stack exchange,提问作者Technical MB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:19:57