表单图片总是上传至第一个问题选项的问题排查
表单图片上传选项定位错误问题
我的表单每个问题都包含输入组件,但在第二个或第三个问题上传图片时,图片总是显示在第一个问题的选项里。看起来系统一直取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 ); } } }
问题分析
- 新选项未添加到目标问题:代码里把
question.options.push(option);注释掉了,导致创建的图片选项根本没加入对应问题的选项列表,后续DOM操作找不到正确位置,只能默认取第一个问题。 - 异步操作顺序错误:
FileReader的onload是异步回调,你在回调外就执行了DOM定位逻辑,此时图片还没读取完成,option的数据也没更新,甚至可能还没被加入数组。 - 索引计算错误:用
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
相关产品推荐
相关产品推荐

