求助:如何实现按数组长度逐题展示带选项的问卷功能
解决逐题展示时题目与选项匹配的问题
嘿,我完全懂你现在的困扰——能显示题目但拿不到对应选项,大概率是题目和选项的关联逻辑没打通,不管是后端数据返回还是前端匹配环节出了问题。我给你一步步拆解解决方案:
第一步:确保数据的关联关系正确
首先得确认你的question_array和choices_array是通过题目ID绑定的,比如每个题目对象里有id字段,每个选项对象里有question_id字段(对应所属题目的ID)。这是后续匹配的核心基础。
第二步:调整Laravel后端,返回关联的题目+选项数据
如果之前你只是单独返回了题目数组,现在需要把每个题目对应的选项一起带回来,这样前端不用自己过滤,更高效也更不容易出错。用Eloquent关联的话很简单:
假设你有Question模型和Choice模型,且Choice模型里定义了和Question的关联:
// app/Models/Choice.php public function question() { return $this->belongsTo(Question::class); }
那控制器里可以这样查询并返回数据:
// 控制器方法 public function getQuestions() { // 拿到所有题目,同时关联对应的选项 $questions = Question::with('choices')->get(); // 转成数组返回给前端 return response()->json([ 'questions' => $questions, ]); }
这样返回的每个题目对象里都会包含一个choices数组,直接对应这道题的所有选项,不用前端再去手动匹配。
如果你的数据不是从Eloquent模型来的,是手动组装的数组,那也要确保每个题目项里嵌套对应的选项数组,比如:
$question_array = [ ['id' => 1, 'title' => '第一题?', 'choices' => [/* 对应选项数组 */]], // ...其他题目 ];
第三步:修改前端display函数,实现单题+选项渲染
假设你已经在前端拿到了后端返回的questions数组,并且有一个currentQuestionIndex变量记录当前显示的题目索引(初始为0):
1. HTML结构(示例)
<div id="question-container"> <h3 id="question-title"></h3> <div id="choices-container"></div> <button id="submit-btn">提交并下一题</button> </div>
2. JavaScript的display函数
let currentQuestionIndex = 0; let questions = []; // 存储后端返回的带选项的题目数组 // 初始化:从后端获取数据 async function init() { const response = await fetch('/api/questions'); // 你的后端接口地址 const data = await response.json(); questions = data.questions; displayCurrentQuestion(); } // 显示当前题目和选项 function displayCurrentQuestion() { if (currentQuestionIndex >= questions.length) { // 所有题目完成,显示结束提示 document.getElementById('question-container').innerHTML = '<h3>所有题目已完成!</h3>'; return; } const currentQuestion = questions[currentQuestionIndex]; // 渲染题目 document.getElementById('question-title').textContent = currentQuestion.title; // 渲染选项 const choicesContainer = document.getElementById('choices-container'); choicesContainer.innerHTML = ''; // 清空之前的选项 currentQuestion.choices.forEach(choice => { const choiceElement = document.createElement('div'); // 这里用单选框示例,你可以改成复选框或其他形式 choiceElement.innerHTML = ` <input type="radio" name="answer" value="${choice.id}" id="choice-${choice.id}"> <label for="choice-${choice.id}">${choice.content}</label> `; choicesContainer.appendChild(choiceElement); }); } // 提交按钮点击事件 document.getElementById('submit-btn').addEventListener('click', () => { // 可选:添加选项验证逻辑 const selectedAnswer = document.querySelector('input[name="answer"]:checked'); if (!selectedAnswer) { alert('请选择一个选项!'); return; } // 可选:把答案提交到后端(如果需要记录) // fetch('/api/submit-answer', { // method: 'POST', // body: JSON.stringify({ // question_id: questions[currentQuestionIndex].id, // choice_id: selectedAnswer.value // }), // headers: { // 'Content-Type': 'application/json', // 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content // } // }); // 切换到下一题 currentQuestionIndex++; displayCurrentQuestion(); }); // 页面加载时初始化 window.onload = init;
如果你暂时没法修改后端,前端手动匹配选项
如果因为某些原因不能调整后端,只能拿到单独的question_array和choices_array,那可以在display函数里根据当前题目的ID过滤选项:
function displayCurrentQuestion() { const currentQuestion = question_array[currentQuestionIndex]; // 过滤出当前题目的选项 const currentChoices = choices_array.filter(choice => choice.question_id === currentQuestion.id); // 后续渲染题目和currentChoices的逻辑和上面一致 }
这样就能保证每次显示的题目都对应正确的选项啦!
内容的提问来源于stack exchange,提问作者shadow_blade
相关产品推荐
相关产品推荐

