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

表单图片总是上传至第一个问题选项的问题排查

表单图片上传选项定位错误问题

我的表单每个问题都包含输入组件,但在第二个或第三个问题上传图片时,图片总是显示在第一个问题的选项里。看起来系统一直取questions数组的[0]位置,而不是图片要插入的目标问题。相关代码如下:

public addOptionImage(question: QuestionModel, e: Event): void {
  if (question.type == "MultipleChoice" || question.type == "SingleChoice") {
    if (!question.options) {
      question.options = [];
    }
    console.log("question: ", question.description);

    const file = (e.target as HTMLInputElement).files[0];
    if (file) {
      // debugger;
      console.log(file);
      let option = new QuestionOptionModel({
        description: file.name,
        imageData: file.name,
      });
      // question.options.push(
      //   new QuestionOptionModel({
      //     description: file.name,
      //   })
      // );

      const reader = new FileReader();
      reader.onload = () => {
        option.imageData = reader.result as string;
        console.log(option.imageData);
      };
      reader.readAsDataURL(file);

      //question.options.push(option);

      this.uploadForm.patchValue({
        image: file,
      });
      this.uploadForm.get("image").updateValueAndValidity();

      //test
      this.changeDetector.detectChanges();

      const qi = this.test.questions.indexOf(question);
      console.log(qi);

      const optionInput = this.getQuestionOptionImageInput(
        qi,
        question.options.length - 1
      );
      optionInput.focus();
      optionInput.setSelectionRange(
        optionInput.value.length,
        optionInput.value.length
      );
    }
  }
}

问题分析

  1. 新选项未添加到目标问题:代码里把question.options.push(option);注释掉了,导致创建的图片选项根本没加入对应问题的选项列表,后续DOM操作找不到正确位置,只能默认取第一个问题。
  2. 异步操作顺序错误:FileReader的onload是异步回调,你在回调外就执行了DOM定位逻辑,此时图片还没读取完成,option的数据也没更新,甚至可能还没被加入数组。
  3. 索引计算错误:用question.options.length - 1获取刚添加的选项索引,但如果option还没被push进去,这个索引会是无效值(比如数组为空时是-1),进而导致DOM定位出错。

修复方案

把创建的选项先加入目标问题的数组,再把依赖option的DOM操作放到onload回调内部,确保异步操作完成后再处理DOM:

public addOptionImage(question: QuestionModel, e: Event): void {
  if (question.type === "MultipleChoice" || question.type === "SingleChoice") {
    if (!question.options) {
      question.options = [];
    }
    console.log("question: ", question.description);

    const file = (e.target as HTMLInputElement).files[0];
    if (file) {
      console.log(file);
      const option = new QuestionOptionModel({
        description: file.name,
        imageData: file.name,
      });
      // 先将选项添加到目标问题的选项数组中
      question.options.push(option);

      const reader = new FileReader();
      reader.onload = () => {
        option.imageData = reader.result as string;
        console.log(option.imageData);
        
        // 异步操作完成后再处理表单和DOM逻辑
        this.uploadForm.patchValue({
          image: file,
        });
        this.uploadForm.get("image").updateValueAndValidity();

        this.changeDetector.detectChanges();

        const qi = this.test.questions.indexOf(question);
        console.log(qi);

        // 此时数组长度-1就是刚添加的选项的正确索引
        const optionInput = this.getQuestionOptionImageInput(
          qi,
          question.options.length - 1
        );
        optionInput.focus();
        optionInput.setSelectionRange(
          optionInput.value.length,
          optionInput.value.length
        );
      };
      reader.readAsDataURL(file);
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:55:20