我正在做一个测验。在单击每个答案的按钮时,将调用ajax函数并返回一个Json响应,该响应会重新加载当前路径,以显示下一个问题或测验的结果(如果已结束)。
如果用户失败,则可以重试新的测验,并且可以重试直到成功。 为此,他单击了结果页面上的提交输入表单。
我的问题是,第一次必须显示结果时,一切正常。我单击提交重试输入以重新启动新表单。我删除了“重试”发布参数。而且,它会在下一个ajax调用之后返回。
有人能解释我发生了什么以及如何永久删除post参数吗?
我的控制器:
ExamController类扩展了控制器{
/**
* Return ExamTaker views
*/
public function indexAction(Request $request, $id){
// get current user
$user = $this->getUser();
// get manager
$em = $this->getDoctrine()->getManager();
// get user stats service
$stats = $this->get('user.stats');
/*************************************/
/* Get usefull datas */
/*************************************/
// get current module group
$module_group = $em->getRepository('UserBundle:ModuleGroup')->findOneById($id);
// check if module group taker exists
$module_group_taker = $this->getDoctrine()->getRepository('UserBundle:ModuleGroupTaker')->findOneBy(array('user' => $user, 'module_group'=>$module_group));
// check if an exam taker is not completed yet
$current_exam_taker = $em->getRepository('UserBundle:ExamTaker')->findOneBy(array('user' => $user, 'module_group' => $module_group, 'completed' => null));
// check if exam is already succeed
$exam_certif_taker = $em->getRepository('UserBundle:ExamCertificationTaker')->findOneBy(array('user' => $user, 'module_group' => $module_group));
// check if an exam is in correction state
$exam_taker_in_correction = $em->getRepository('UserBundle:ExamTaker')->getExamInCorrection($user, $module_group);
/**************************************/
/* Security : access not allowed to */
/* expired supervisor */
/**************************************/
$ac = $this->get('security.authorization_checker');
if (($ac->isGranted('ROLE_SUPERVISOR') || $ac->isGranted('ROLE_MANAGER')) && $user->getExpiration()->format('YmdHis') < date('YmdHis')) {
throw $this->createAccessDeniedException();
}
/********************************************/
/* if user already succeed with score 20/20 */
/********************************************/
if($exam_certif_taker && $exam_certif_taker->getExamTaker()->getScore() == 20){
dump('1');
// return results view
return $this->render('UserBundle:exam:examresults.html.twig', array(
'exam' => $exam_certif_taker->getExamTaker(),
'exam_certif' => $exam_certif_taker,
'certification' => $user->getCertification()
));
}
/********************************************/
/* if user already succeed with less than */
/* 20/20 and wants to retry */
/********************************************/
else if($exam_certif_taker && $exam_certif_taker->getTries() == 1 && $request->request->get('retry') && !$user->getCertification()){
dump('2');
$request->request->remove('retry');
$request->request->setContent(null);
$exam_taker_in_correction->setCorrected(new \DateTime());
$exam_taker = $this->createNewExamTaker($user, $module_group);
$next_question = $this->prepareNextExamQuestion(1, $exam_taker);
return $this->render('UserBundle:exam:exam.html.twig', array(
'size' => count($exam_taker->getQuestions()),
'title' => $module_group->getTitle(),
'question' => $next_question,
'color' => $module_group->getColor(),
'exam_taker' => $exam_taker
));
}
/********************************************/
/* if user already succeed with less than */
/* 20/20 and an exam taker is not completed */
/********************************************/
else if($exam_certif_taker && $current_exam_taker){
dump('3');
$next_exam_answer_taker = $em->getRepository('UserBundle:ExamAnswerTaker')->findOneBy(array('exam' => $current_exam_taker, 'answer' => null));
$next_question = $next_exam_answer_taker->getQuestion();
return $this->render('UserBundle:exam:exam.html.twig', array(
'size' => count($current_exam_taker->getQuestions()),
'title' => $module_group->getTitle(),
'question' => $next_question,
'color' => $module_group->getColor(),
'exam_taker' => $current_exam_taker
));
}
/********************************************/
/* for all other cases user has succeed */
/* return results */
/********************************************/
else if($exam_certif_taker){
dump('4');
// return results view
return $this->render('UserBundle:exam:examresults.html.twig', array(
'exam' => $exam_certif_taker->getExamTaker(),
'exam_certif' => $exam_certif_taker,
'certification' => $user->getCertification()
));
}
/********************************************/
/* if user failed and wants to retry */
/********************************************/
else if($exam_taker_in_correction && $request->request->get('retry')){
dump('5');
$request->request->remove('retry');
$exam_taker_in_correction->setCorrected(new \DateTime());
$exam_taker = $this->createNewExamTaker($user, $module_group);
$next_question = $this->prepareNextExamQuestion(1, $exam_taker);
return $this->render('UserBundle:exam:exam.html.twig', array(
'size' => count($exam_taker->getQuestions()),
'title' => $module_group->getTitle(),
'question' => $next_question,
'color' => $module_group->getColor(),
'exam_taker' => $exam_taker
));
}
/********************************************/
/* if user failed and didn't ask to retry */
/********************************************/
else if($exam_taker_in_correction){
dump('6');
// return results view
return $this->render('UserBundle:exam:examresults.html.twig', array(
'exam' => $exam_taker_in_correction,
'exam_certif' => false,
'certification' => false
));
}
/********************************************/
/* if an exam is not completed yet */
/********************************************/
else if($current_exam_taker){
dump('7');
$next_exam_answer_taker = $em->getRepository('UserBundle:ExamAnswerTaker')->findOneBy(array('exam' => $current_exam_taker, 'answer' => null));
$next_question = $next_exam_answer_taker->getQuestion();
return $this->render('UserBundle:exam:exam.html.twig', array(
'size' => count($current_exam_taker->getQuestions()),
'title' => $module_group->getTitle(),
'question' => $next_question,
'color' => $module_group->getColor(),
'exam_taker' => $current_exam_taker
));
}
/********************************************/
/* all other cases, create a new exam taker */
/********************************************/
else {
dump('8');
$exam_taker = $this->createNewExamTaker($user, $module_group);
$next_question = $this->prepareNextExamQuestion(1, $exam_taker);
return $this->render('UserBundle:exam:exam.html.twig', array(
'size' => count($exam_taker->getQuestions()),
'title' => $module_group->getTitle(),
'question' => $next_question,
'color' => $module_group->getColor(),
'exam_taker' => $exam_taker
));
}
}
/**
* ajax function to save current answer
* and return either results or next question
*/
function saveAction(Request $request){
//Prepare usefull datas
$em = $this->getDoctrine()->getManager();
$exam_taker_id = $request->request->get('exam_taker_id');
$current_question_id = $request->request->get('question_id');
$answer_id = $request->request->get('answer_id');
$exam_taker = $em->getRepository('UserBundle:ExamTaker')->findOneById($exam_taker_id);
$current_question = $em->getRepository('UserBundle:ExamQuestion')->findOneById($current_question_id);
$exam_answer = $em->getRepository('UserBundle:ExamAnswer')->findOneById($answer_id);
$exam_answer_taker = $em->getRepository('UserBundle:ExamAnswerTaker')->findOneBy(array('exam'=> $exam_taker, 'question' => $current_question));
$level = $current_question->getLevel();
$next_question = false;
$module_group = $exam_taker->getModuleGroup();
$user = $exam_taker->getUser();
//save answer taker
$exam_answer_taker->setAnswer($exam_answer);
$em->flush();
// get array of exam taker questions already displayed
$exam_taker_questions = $exam_taker->getQuestions();
$count_questions = count($exam_taker_questions);
// Check if last answer is good
$good_answer = $em->getRepository('UserBundle:ExamAnswer')->findOneBy(array('question' => $current_question, 'correct' => true));
($good_answer === $exam_answer_taker->getAnswer()) ? $check_answer = true : $check_answer = false;
// update correct var
if($check_answer){
$exam_answer_taker->setCorrect(1);
} else {
$exam_answer_taker->setCorrect(0);
}
// Update last answer given
$em->flush();
// count answers group by level
$array_answers = array(
'1' => array('success' => 0, 'fail' => 0),
'2' => array('success' => 0, 'fail' => 0),
'3' => array('success' => 0, 'fail' => 0),
'4' => array('success' => 0, 'fail' => 0),
'5' => array('success' => 0, 'fail' => 0)
);
foreach ($exam_taker->getAnswers() as $answer) {
if($answer->getCorrect()){
switch ($answer->getQuestion()->getLevel()) {
case '1':
$array_answers['1']['success'] += 1;
break;
case '2':
$array_answers['2']['success'] += 1;
break;
case '3':
$array_answers['3']['success'] += 1;
break;
case '4':
$array_answers['4']['success'] += 1;
break;
case '5':
$array_answers['5']['success'] += 1;
break;
}
} else {
switch ($answer->getQuestion()->getLevel()) {
case '1':
$array_answers['1']['fail'] += 1;
break;
case '2':
$array_answers['2']['fail'] += 1;
break;
case '3':
$array_answers['3']['fail'] += 1;
break;
case '4':
$array_answers['4']['fail'] += 1;
break;
case '5':
$array_answers['5']['fail'] += 1;
break;
}
}
}
// if count questions is 20
if($count_questions == 20){
// set completed to end current exam
$exam_taker->setCompleted(new \DateTime());
// check if good answer to the current question
if($check_answer){
// set score depending on successes
if($array_answers['5']['success'] == 3){ // if 3 success level 5, set score to 20
$exam_taker->setScore(20);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else if($array_answers['4']['success'] == 3){ // if 3 success level 4, set score to 16
$exam_taker->setScore(16);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else if($array_answers['3']['success'] == 3){ // if 3 success level 3, set score to 14
$exam_taker->setScore(14);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else if($array_answers['2']['success'] == 3){ // if success level 2, set score to 12
$exam_taker->setScore(12);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else {
$exam_taker->setScore(0);
}
} else {
switch ($level) {
case 5:
if($array_answers['5']['fail'] == 2){ // if 2 fail level 5, set score to 16
$exam_taker->setScore(16);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else if($array_answers['4']['fail'] == 3){ // if 3 fail level 4, set score 14
$exam_taker->setScore(14);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else if($array_answers['3']['fail'] == 3){ // if 3 fail level 3, set score 12
$exam_taker->setScore(12);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else {
$exam_taker->setScore(0);
}
break;
case 4:
if($array_answers['4']['fail'] == 3){ // if 3 fail level 4, set score 14
$exam_taker->setScore(14);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else if($array_answers['3']['fail'] == 3){ // if 3 fail level 3, set score 12
$exam_taker->setScore(12);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else {
$exam_taker->setScore(0);
}
break;
case 3:
if($array_answers['3']['fail'] == 3){ // if 3 fail level 3, set score 12
$exam_taker->setScore(12);
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else {
$exam_taker->setScore(0);
}
break;
case 2:
$exam_taker->setScore(0);
break;
case 1:
$exam_taker->setScore(0);
break;
}
}
} else { // if not 20 questions yet
// check if good answer to the current question
if($check_answer){
if(($level == 5) && ($array_answers['5']['success'] == 3)){
$exam_taker->setScore(20);
$exam_taker->setCompleted(new \DateTime());
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else if($level == 5){
$next_question = $this->prepareNextExamQuestion(5, $exam_taker);
} else if($level == 4){
$next_question = $this->prepareNextExamQuestion(5, $exam_taker);
} else if($level == 3){
$next_question = $this->prepareNextExamQuestion(4, $exam_taker);
} else if($level == 2){
$next_question = $this->prepareNextExamQuestion(3, $exam_taker);
} else if($level == 1){
$next_question = $this->prepareNextExamQuestion(2, $exam_taker);
}
} else {
switch ($level) {
case 5 :
if($array_answers['5']['fail'] == 2){ // if 2 fail level 5, set score to 16
$exam_taker->setScore(16);
$exam_taker->setCompleted(new \DateTime());
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else {
$next_question = $this->prepareNextExamQuestion(4, $exam_taker);
}
break;
case 4 :
if($array_answers['4']['fail'] == 3){ // if 3 fail level 4, set score to 14
$exam_taker->setScore(14);
$exam_taker->setCompleted(new \DateTime());
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else {
$next_question = $this->prepareNextExamQuestion(3, $exam_taker);
}
break;
case 3 :
if($array_answers['3']['fail'] == 3){ // if 3 fail level 3, set score to 12
$exam_taker->setScore(12);
$exam_taker->setCompleted(new \DateTime());
$this->createNewExamCertificationTaker($exam_taker, $user, $module_group);
} else {
$next_question = $this->prepareNextExamQuestion(2, $exam_taker);
}
break;
case 2 :
if($array_answers['2']['fail'] == 4){ // if 4 fail level 2, stop exam
$exam_taker->setScore(0);
$exam_taker->setCompleted(new \DateTime());
} else {
$next_question = $this->prepareNextExamQuestion(1, $exam_taker);
}
break;
case 1 :
if($array_answers['1']['fail'] == 5){ // if 5 fail level 1, stop exam
$exam_taker->setScore(0);
$exam_taker->setCompleted(new \DateTime());
} else {
$next_question = $this->prepareNextExamQuestion(1, $exam_taker);
}
break;
}
}
}
$em->flush();
// return next question to continue the current exam
return new JsonResponse();
}
/**
* Add next question to current exam taker
*/
public function prepareNextExamQuestion($level, $exam_taker){
// get manager
$em = $this->getDoctrine()->getManager();
// prepare test questions random array
// without questions already used
if(count($exam_taker->getQuestions()) > 0){
$questions_by_level = $em->getRepository('UserBundle:ExamQuestion')->getUnusedQuestionByLevel($level, $exam_taker->getModuleGroup(), $exam_taker->getQuestions());
} else {
$questions_by_level = $em->getRepository('UserBundle:ExamQuestion')->getUnusedQuestionByLevel1($level, $exam_taker->getModuleGroup());
}
// set a random question to display (the result is an array)
$random_question_id = array_rand($questions_by_level, 1);
$random_question = $questions_by_level[$random_question_id];
// add question to exam taker
$exam_taker->addQuestion($random_question);
$random_question->addExam($exam_taker);
// create exam answer taker
$exam_answer_taker = new ExamAnswerTaker();
$exam_answer_taker->setExam($exam_taker);
$exam_answer_taker->setQuestion($random_question);
$exam_taker->addAnswer($exam_answer_taker);
$em->persist($exam_answer_taker);
$em->flush();
return $random_question;
}
/**
* create or update a new exam certification taker
*/
public function createNewExamCertificationTaker($exam_taker, $user, $module_group){
// get manager
$em = $this->getDoctrine()->getManager();
// check if exam certification taker already exists
$exam_certif_taker = $em->getRepository('UserBundle:ExamCertificationTaker')->findOneBy(array('user' => $user, 'module_group' => $module_group));
if($exam_certif_taker){
$exam_certif_taker->setCompleted(new \DateTime());
$exam_certif_taker->getTries() == null ? $exam_certif_taker->setTries(1) : $exam_certif_taker->setTries(2);
} else {
$exam_certif_taker = new ExamCertificationTaker();
$exam_certif_taker->setExamTaker($exam_taker);
$exam_certif_taker->setUser($user);
$exam_certif_taker->setModuleGroup($module_group);
$exam_certif_taker->setCompleted(new \DateTime());
$exam_certif_taker->setTries(1);
$em->persist($exam_certif_taker);
}
}
/**
* Create a new Exam Taker
*/
public function createNewExamTaker($user, $module_group){
// get manager
$em = $this->getDoctrine()->getManager();
$exam_taker = new ExamTaker();
$exam_taker->setUser($user);
$exam_taker->setModuleGroup($module_group);
$em->persist($exam_taker);
$em->flush();
return $exam_taker;
}}
视图中带有重试输入的行:
<form method="post" action="{{ path('user_exam_index', {'id': exam.moduleGroup.id}) }}">
<input type="submit" name="retry" class="waves-btn primary margin-top" value="Recommencer le quiz">
</form>
js函数:
function initAjaxSaveExamAnswer(exam_taker_id, question_id) {
$('body').on('click', '.initAjaxSaveExamAnswer', function(e){
e.preventDefault();
// check if an answer is checked
if (!$('input:radio[name="question"]:checked').val()) {
e.preventDefault();
alert("Tu dois choisir au moins une réponse !");
return;
}
var answer_id = $('input:radio[name="question"]:checked').val();
$.ajax({
type: "POST",
url: Routing.generate('user_exam_save'),
data: {exam_taker_id: exam_taker_id, question_id: question_id, answer_id: answer_id},
dataType: "json"
})
.done(function (data) {
location.reload();
})
.fail(function (jqXHR, textStatus, errorThrown) {
alert('Une erreur s\'est produite. Veuillez réessayer votre action...');
});
});
}
编辑:
这是过程:我显示第一个带有单选按钮答案的问题。然后,我单击一个启动ajax功能的按钮。 Ajax函数检查答案是否正确,例如,如果答案错误太多,则计算下一个问题以显示或结束测验。在这两种情况下,ajax函数都将返回location.reload();
。由于控制器中的indexAction(),页面得以重新加载。测验结束后,将显示结果视图,其中包含带有“重试提交”按钮的表单。我单击提交重试按钮以重新开始新测验。然后调用indexAction()并返回新测验的新第一个问题。同时,我删除了retry参数。但是我可以看到请求内容仍然包含有关重试参数的信息。也许这是一个线索?好了,此时重试参数已被删除。但是,当我验证第一个答案时,出现下一个问题,并且重试参数又返回到请求中,这很糟糕,因为由于这种不良行为,结果视图永远无法显示。