【Angular2】Question组件设计

引言

【Angular2】ExamPaper组件设计 中说到ExamPaper组件作为各种题型组件的容器,用于选择和传递数据

目前设计的题型组件有5个,可以适应12种题型,分别为radio、sub-radio、input、checkbox、textarea,具体实现都类似,那么就以最常用的radio组件来说明

 

功能要求

1.根据数据的类型渲染显示数据;
2.提交用户的填入的数据;
3.将用户的数据回显在原来的位置;

 

代码说明

html code

 <p>{{question.questionMainOrder + ". " + question.questionContent}}p>
    <div  *ngFor="let option of question.questionSubList;let i=index">
        <div *ngIf="question.studentAnswerArray">
                <input  type="radio" name="{{option.questionMainId}}"  value="{{option.optionsContent}}"  
                checked="{{option.optionsContent==question.studentAnswerArray[0] ? 'checked' : ''}}"
                (click)="updateAnswer($event.target, $event.target.value)">
                {{alphabet[i]}}{{'. '+option.optionsContent}}
        div>
        <div *ngIf="!question.studentAnswerArray">
                <input  type="radio" name="{{option.questionMainId}}"  value="{{option.optionsContent}}"  
                (click)="updateAnswer($event.target, $event.target.value)">
                {{alphabet[i]}}{{'. '+option.optionsContent}}
        div>
     div>

html 说明

这里把题目id存到了每道题的name中,因为在设计AnswerSheet组件的时候把题目id已经用到了id上了,所以这里只好放在name中,其实应该调换一下,不过改动量比较大,而且当前也能实现;

通过两个ngIf来判断返回的题目中是否有用户答案,如果有则显示;

这里的用户采用数组的形式,无论选择,多选,还是填空,都是数组,因为一道题的答案可能有多个,需要渲染在相应的位置,所以答案之间必须是分开的,采用数组形式就可以解决;


ts code

@Input() question: QuestionMainModel; //题干实体
@Input() paperId: string; //试卷ID
@Input() questionTypeId: string; //题型ID
@Output() updatedAnswer = new EventEmitter();
alphabet = Alphabet;
done: boolean = false;

updateAnswer(el: Element, value: string) {
    //用户的答案(在方法内声明,每次提交为新答案实体,simplechange才会识别)
    let answer: Answer = new Answer;
    //声明数组
    answer.studentAnswerArray = [];

    //获得题目id
    let questionid: string = el.getAttribute("name");

    //处理用户答案
    answer.studentId = localStorage.getItem("userId");
    answer.paperId = this.paperId;
    answer.questionTypeId = this.questionTypeId;
    answer.questionMainId = questionid;
    answer.studentAnswerArray[0] = value;
    answer.done = true;
    console.log("question-radio-answer--" + answer);

    //传递用户的答案
    this.updatedAnswer.emit(answer);
    this.updateStudentAnswerToBackend(answer);
  }

  /* 向后台提交学生答案 */
  public updateStudentAnswerToBackend(answer: Answer) {
    let url: string = "examinationEvaluation-web/onlineExam/updatePaperRecordByRecord" + this.authGuardService.getTicket();
    let body: string = JSON.stringify(answer);
    this.exampapaerservice.post(url, body).subscribe(
      res => {
        if (res.json().data != true) {
          let ns: number = parseInt(localStorage.getItem("NetWorkState"));
          ns = ns + 1;
          localStorage.setItem("NetWorkState", ns.toString());
        }
      }
    );
  }

ts 说明

在实时提交答案的过程中,每次必须是new一个新的实体,不然AnswerSheet中SimpleChange无法监测到;

同时向后端提交答案的时候,需要对返回值进行判断,如果提交失败则修改localstorage中的NetWorkState值,在Information组件中timer会每秒读取这个值,来监测网络状态;

 

小结

Question组件中的5个题型组件的逻辑是类似的,只是实现方式不太一样;

关于input题型组件很简单,就不加赘述;

checkbox题型组件涉及的难点在 【Angular2】CheckBox获取值的两种方式 中已说明;

textarea题型组件涉及到的难点在格式的保存与显示,在【Angular2】简易版富文本编辑器【Angular2】通过Pipe使用InnerHTML 已经说明

你可能感兴趣的:(………Angular2)