JavaScript が参照によってオブジェクトを渡すことを知っているため、次のコードで多くの問題が発生しています。
function doGradeAssignmentContent(dtos) {
var x = 5;
var allPages = [];
var stage = new App.UI.PopUpDisplay.PopUpStageAssignmentGrader(null, that);// pass launch element
for(var i = 0; i < dtos[0].result.students.length; ++i) {
var pagesSet = [];
for(var j = 0; j < dtos[0].result.questions.length; ++j) {
var questionObject = jQuery.extend(true, {}, new Object());
questionObject = dtos[0].result.questions[j];
if(dtos[0].result.students[i].answers[j].assignmentQuestionId === questionObject.questionId) {// expected, if not here something is wrong
questionObject.answer = dtos[0].result.students[i].answers[j].studentAnswer;
questionObject.pointsReceived = dtos[0].result.students[i].answers[j].pointsReceived;
} else {
var theAnswer = findAssociatedStudentAnswer(questionObject.questionId, dtos[0].result.students[i].answers[j]);
if(theAnswer !== null) {
questionObject.answer = theAnswer.studentAnswer;
questionObject.pointsReceived = theAnswer.pointsReceived;
} else {
alert("Unexpected error. Please refresh and try again.");
}
}
pagesSet[pagesSet.length] = new App.UI.PopUpDisplay.StageAssignmentGradingPages[dtos[0].result.questions[j].questionType.charAt(0).toUpperCase() + dtos[0].result.questions[j].questionType.slice(1) + "QuestionAssignmentGradingPage"](j + 1, questionObject);
}
var studentInfo = {};
studentInfo.avatar = dtos[0].result.students[i].avatar;
studentInfo.displayName = dtos[0].result.students[i].displayName;
stage.addPageSet(pagesSet, studentInfo);
}
stage.launch();
}
最初に、結果 (dtos) がどのように見えるかを示して、この関数がどのように解析しているかをよりよく理解できるようにします。
結果 (dtos) はオブジェクトで、次のようになります。
- dtos 配列
- dtos[0]、常にここに静的
- dtos[0].result、常にここに静的
- dtos[0].questions 配列
- dtos[0].questions.index0 - indexN. これは私たちの質問を記述し、それぞれがオブジェクトです
- dtos[0].students 配列
- dtos[0].students[0]-[n].answers 配列。各学生配列/オブジェクトには Answers 配列があります。各生徒は、dtos[0].questions にある質問と同じ数の要素をこの Answers 配列に持ちます。各要素はオブジェクトです
ここで行うことは、この Object ステージを作成することです。ここで重要なのは、「this.studentsPages」という配列があることです。この配列には、最終的に dtos[0].students 内の学生と同じ数のエントリが含まれます。
したがって、この for ループをループして dtos 配列を分析し、pagesSet 配列を作成します。ここに私の問題があります。for ループの最初の繰り返しで、この questionObject 要素を作成します。私も var questionObject = {} を試してみましたが、今表示されているのは、私が見ていた問題を修正する試みに過ぎませんでしたが、どちらもうまくいきませんでした。
したがって、外側の for ループの最初の繰り返しの最後で、stage.addPageSet を呼び出します。これがここで行われることです。
var pageObject = [];
pageObject["questions"] = pageSet;
pageObject["displayName"] = studentInfo.displayName;
this.studentsPages[this.studentsPages.length] = pageObject;
if(this.studentsPages.length === 1) {// first time only
for(var i = 0; i < pageSet.length; ++i) {
this.addPage(pageSet[i]);
}
}
ここで注目すべき重要な点は、最初の呼び出しの前に空の配列だった this.studentsPages に pageObject を追加する場所です。pageObject には、pageSet に加えて、もう少し多くの情報が含まれるようになりました。pageSet はオブジェクトであり、参照によって渡されたことを思い出してください。
for ループの次の反復で、次の行にヒットすると:
questionObject.answer = dtos[0].result.students[i].answers[j].studentAnswer;
それはうまくいきません。これにより、questionObject のローカル コピーが変更されますが、最初の繰り返しで addPageSet に渡され、studentsPages 配列に追加された questionObjec のコピーも変更されます。したがって、生徒が 2 人しかいなかった場合、結局のところ、studentPages には 2 つの同一のオブジェクトが保持されます。これは真実であってはなりません。
問題は、doGradeAssignmentContent 関数の questionObject が、前の反復で作成されたオブジェクトへの参照を保持し、その後のすべての反復でそれをオーバーライドすることです。
これを修正するにはどうすればよいですか?
助けてくれてありがとう!