编辑 this is my full project in stackblitz 课程测验位于“课程测验”文件夹中(课程测验是课程测验的父级)
我正在尝试建立一个独立于页面的测验(每个页面有一个问题)。我正在使用分页进行此操作。 数据从后端传递,并且html和http请求没有问题。 我不需要将答案保存到数据库,因此我想以某种方式使用本地数组。
如果我检查答案并移至另一页面并返回该页面,则数据已消失。 我不知道要使用哪种数据结构(也许是int数组?),而且因为仅在最后一页提交按钮,我不知道何时进行更新(设置寻呼机时?)。如何使用formGroup保存数据? 到目前为止,这是我的代码:
组件
import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute, Router, Routes, NavigationEnd } from '@angular/router';
import { FormControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ICourse } from '../../course';
import { ISegment } from '../../course';
import { IQuestion } from '../../course';
import { CourseService } from '../../course.service';
import { PagerService } from '../../pager.service';
import * as _ from 'underscore';
@Component({
selector: 'quiz-course',
templateUrl: './course-quiz.component.html',
styleUrls: ['./course-quiz.component.sass']
})
export class CourseQuizComponent implements OnInit {
// the data I get from course-play component
@Input() items: IQuestion[];
// variables for pagination
pagedItems: IQuestion[];
pager: any = {};
answersArray: any[]; // array of answers the user choose
index: int; // current index of answersArray
sum: int; // number of answers the user answered
public quizForm: FormGroup // radio buttons in the quiz form
constructor(private courseService: CourseService,
private route: ActivatedRoute,
private router: Router,
private fb: FormBuilder,
private pagerService: PagerService) { }
ngOnInit() {
this.setPage(1);
this.index = 0;
this.sum = 0;
this.checked = false;
this.quizForm = this.fb.group({
selected: [{value: ''}, [Validators.required]]
});
}
// change pages
setPage(page: number) {
if (page < 1 || page > this.pager.totalPages) {
return;
}
// get pager object from service
this.pager = this.pagerService.getPager(this.items.length, page);
// get current page of items
this.pagedItems = this.items.slice(this.pager.startIndex, this.pager.endIndex + 1);
// do something here to update answersArray
}
// getter for easy access to form fields
get f() {
return this.quizForm.controls;
}
// insert to local array the answers of the user after he press submit
onSubmit() {
// if we answered all answers, go to finish page
if (this.sum == this.items.length) { }
}
}
html
<!-- If the user didn't answer all the questions -->
<div class="container" *ngIf="sum < pager.totalPages">
<div class="text-left quiz-body" *ngFor="let item of pagedItems">
<form [formGroup]="quizForm" (ngSubmit)="onSubmit()">
<!-- items being paged -->
<h3>Question {{item.id}}/{{items.length}}</h3>
<h6>Question {{item.question}}</h6>
<div class="form-group">
<mat-radio-group FormControlName="selected" class="form-control">
<ul class="items">
<li><mat-radio-button color="primary" id="answer1" value="1"></mat-radio-button><label for="answer1">1. {{item.answer1}}</label></li>
<li><mat-radio-button color="primary" id="answer2" value="2"></mat-radio-button><label for="answer2">2. {{item.answer2}}</label></li>
<li><mat-radio-button color="primary" id="answer3" value="3"></mat-radio-button><label for="answer3">3. {{item.answer3}}</label></li>
<li><mat-radio-button color="primary" id="answer4" value="4"></mat-radio-button><label for="answer4">4. {{item.answer4}}</label></li>
</ul>
</mat-radio-group>
</div>
<!-- Submit Buttom will show only on the last page -->
<div *ngIf="pager.currentPage == pager.totalPages">
<button type="submit" class="btn btn-primary mb-2">Submit</button>
</div>
<!-- pager -->
<ul *ngIf="pager.pages && pager.pages.length" class="pagination">
<li class="page-item" [ngClass]="{disabled:pager.currentPage === 1}">
<a class="page-link" (click)="setPage(1)">First</a>
</li>
<li class="page-item" [ngClass]="{disabled:pager.currentPage === 1}">
<a class="page-link" (click)="setPage(pager.currentPage - 1)">Previous</a>
</li>
<li class="page-item" *ngFor="let page of pager.pages" [ngClass]="{active:pager.currentPage === page}">
<a class="page-link" (click)="setPage(page)">{{page}}</a>
</li>
<li class="page-item" [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
<a class="page-link" (click)="setPage(pager.currentPage + 1)">Next</a>
</li>
<li class="page-item" [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
<a class="page-link" (click)="setPage(pager.totalPages)">Last</a>
</li>
</ul>
</form>
</div>
</div>
<!-- If the user finished the quiz, this div will displaying instead -->
<div class="container" *ngIf="sum == pager.totalPages">
<h3> You have just finished the quiz! </h3>
</div>
编辑:
这是分页服务:
import * as _ from 'underscore';
export class PagerService {
getPager(totalItems: number, currentPage: number = 1, pageSize: number = 1) {
// calculate total pages
let totalPages = Math.ceil(totalItems / pageSize);
let startPage: number, endPage: number;
// if (totalPages <= 10) {
// // less than 10 total pages so show all
// startPage = 1;
// endPage = totalPages;
// } else {
// // more than 10 total pages so calculate start and end pages
// if (currentPage <= 6) {
// startPage = 1;
// endPage = 10;
// } else if (currentPage + 4 >= totalPages) {
// startPage = totalPages - 9;
// endPage = totalPages;
// } else {
// startPage = currentPage - 5;
// endPage = currentPage + 4;
// }
// }
if (totalPages <= 5) {
startPage = 1;
endPage = totalPages;
} else {
if (currentPage <= 3) {
startPage = 1;
endPage = 5;
} else if (currentPage + 1 >= totalPages) {
startPage = totalPages - 4;
endPage = totalPages;
} else {
startPage = currentPage - 2;
endPage = currentPage+2;
}
}
// calculate start and end item indexes
let startIndex = (currentPage - 1) * pageSize;
let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);
// create an array of pages to ng-repeat in the pager control
let pages = _.range(startPage, endPage + 1);
// return object with all pager properties required by the view
return {
totalItems: totalItems,
currentPage: currentPage,
pageSize: pageSize,
totalPages: totalPages,
startPage: startPage,
endPage: endPage,
startIndex: startIndex,
endIndex: endIndex,
pages: pages
};
}
}
答案 0 :(得分:0)
如果我是你,我会转而路由整个问题模块并使用sharign服务来处理该问题。
我快速stackblitz向您展示了一个示例。
当然可以改进,但这只是为了让您对我的想法有所了解。
我认为您的情况是路由的完美示例。不仅如此,使用这种方法,您的代码将变得更具可读性,可重用性和清晰性。
答案 1 :(得分:-1)
编辑
您可以通过订阅无线电组变更值事件来实现所选答案的保存:
this.formGroup.controls['selected'].valueChanges.subscribe(value => {
// TODO: save selected abswer in the array
});