Как я могу перейти к определенной викторине на основе quizId?

Я работаю над компонентом выбора викторины. Я хотел бы, чтобы он направлялся к определенному тесту на основе quiz.id в массиве QUIZ_DATA во внешнем файле quiz.ts, например, TS-Quiz или DI-Quiz. Когда я нажимаю викторину TypeScript (TS-Quiz), я получаю введение DI-Quiz; это должна быть вводная информация TS-Quiz. Не знаю, как использовать тип quiz.id, который передается в IntroductionComponent в [routerLink].

И я получаю эту ошибку при загрузке первого вопроса викторины: TypeError: Cannot read property '0' of undefined

Я бы хотел, чтобы сначала была страница выбора (сделано), затем вводная (на основе quiz.id), затем вопросы (на основе quiz.id), затем результаты.

Пожалуйста, посмотрите мое работающее приложение на Stackblitz: https://stackblitz.com/edit/angular-10-quiz-app

Мой [routerLink] ниже:

<mat-grid-tile *ngFor="let quiz of quizData"
  [routerLink]="['/quiz/intro', quiz.id]"
  [ngStyle]="{ 'background': 'url(' + quiz.imageUrl + ') no-repeat center top',
               'background-size': '380px 275px' }">

Мой IntroductionComponent выглядит так:

<ng-container *ngFor="let quiz of quizData">
  <mat-card *ngIf="quiz.id === 'DI_Quiz'">
    <mat-card-header>
      <div mat-card-avatar class="header-image"></div>
      <mat-card-title i18n>{{ quiz.milestone }} Quiz</mat-card-title>
      <mat-card-subtitle i18n>
        <span>How well do you know {{ quiz.milestone }}?</span>
        <span>Take the quiz and find out!</span>
      </mat-card-subtitle>
    </mat-card-header>
...
<mat-card-actions>
  <button class="btn btn-outline-primary" routerLink="/quiz/question/1">
     <span i18n><strong>Start the Quiz!</strong></span>
  </button>
</mat-card-actions>

А вот моя настройка маршрутизации в моем quiz-routing.module.ts:

const routes: Routes = [
  { path: '', redirectTo: 'select' },
  { path: 'select', component: QuizSelectionComponent },
  { path: 'intro', component: IntroductionComponent },
  { path: 'intro/:id', component: IntroductionComponent },
  { path: 'question', component: QuizComponent },
  { path: 'question/:questionIndex', component: QuizComponent },
  { path: 'results', component: ResultsComponent }
];

person integral100x    schedule 13.07.2020    source источник


Ответы (2)


Глядя на метод quiz.component.ts в getQuestion (line 85), метод getQuestions службы викторин возвращает массив, а не объект. Таким образом, имущественные вопросы останутся неопределенными.

Похоже, что идентификатор викторины отсутствует, вам нужно получить идентификатор викторины, чтобы получить вопросы этой викторины, что-то вроде этого:

this.question = this.quizService.getQuestions()[indexOfQuizId].questions[this.questionIndex - 1];

Чтобы получить indexOfQuizId, один из подходов - изменить маршрут страницы вопроса на:

{ path: 'question/:quizId/:questionIndex', component: QuizComponent, pathMatch: 'full' },

а затем получить индекс викторины с чем-то вроде этого:

const quizId = this.activatedRoute.snapshot.paramMap.get('quizId');
const indexOfQuizId = this.quizData.findIndex(el => el.id === quizId);

Конечно, есть и другие способы сделать это, это только один из способов.

Надеюсь, это поможет.

person Danilo Torchio    schedule 13.07.2020
comment
Спасибо, у меня возникли проблемы с получением индекса идентификатора теста, попробуйте следующее: const indexOfQuizId = this.quizData.findIndex((element ) => element.id === this.quizName); console.log(indexOfQuizId) дает -1 - person integral100x; 13.07.2020
comment
У меня все еще есть эта проблема. Это необходимо для отображения вопросов викторины. Пожалуйста, не могли бы вы помочь. Спасибо. - person integral100x; 14.07.2020
comment
Вы можете изменить свой маршрут, чтобы получить название викторины, а затем получить индекс, я улучшу свой ответ на примере. - person Danilo Torchio; 15.07.2020
comment
Спасибо. Я добавил код в свой Stackblitz и обновил routerLink на кнопке «Начать викторину» в IntroductionComponent на [routerLink]=['/question/', quiz.id, 1], и когда я нажимаю кнопку в моем IntroductionComponent, ничего не происходит, никаких сообщений в консоли и ничего не отображается. - person integral100x; 15.07.2020
comment
Я обновил quizData: Quiz[] и использование quizData и this.question в QuizService для нескольких тестов. - person integral100x; 15.07.2020
comment
getQuestions () и numberOfQuestions () в QuizService кажутся проблемой, я получаю эту ошибку: Не удается прочитать «вопросы» свойства неопределенного - person integral100x; 16.07.2020
comment
Я все еще получаю эту ошибку, ничего не отображается. - person integral100x; 17.07.2020
comment
Я видел, что вы пытаетесь получить параметры анкеты напрямую из сервиса, лучше сделать это в своем компоненте и передать параметры в сервис, чтобы не было проблем как у вас сейчас. - person Danilo Torchio; 17.07.2020
comment
Я думаю, вам нужно пересмотреть поток вашего заявления и помнить о разделении обязанностей. Есть несколько вещей, которые вам нужно решить, и это начинает выходить за рамки этой проблемы. - person Danilo Torchio; 17.07.2020
comment
Я переработал код, чтобы получить параметры в QuizComponent, и попытаюсь передать totalQuestions в QuizService, а также в ScoreComponent и ScoreboardComponent. - person integral100x; 17.07.2020
comment
Спасибо, маршрутизация вопросов викторины теперь работает! Мат-аккордеон не расширяется в ResultsComponent (*ngFor имеет нерешенные переменные вопросы). Также я только что заметил в своей викторине, что correctMessage остается неизменным в викторине DI для всех вопросов, когда викторина начинается с вопроса с несколькими вариантами ответов. - person integral100x; 18.07.2020
comment
Я передал вопросы в ResultsComponent, и мат-аккордеон теперь работает, пытаясь установить и передать ресурсы аналогичным образом... - person integral100x; 18.07.2020
comment
Корректное сообщение, кажется, отображается нормально для всех вопросов в Stackblitz, но, похоже, не отображается правильно локально в IntelliJ... - person integral100x; 19.07.2020
comment
Переменная correctMessage была инициализирована в ngOnInit и setSelected, удалена из ngOnInit, и теперь она работает нормально. - person integral100x; 21.07.2020

Параметр маршрутизации можно получить следующим образом:

Обновите свой introduction.component.ts, как показано ниже,

import { ChangeDetectionStrategy, Component } from '@angular/core';

import { QUIZ_DATA } from '../../shared/quiz';
import { Quiz } from '../../shared/models/Quiz.model';
import { Router, ActivatedRoute, ParamMap } from '@angular/router';


@Component({
  selector: 'codelab-quiz-intro',
  templateUrl: './introduction.component.html',
  styleUrls: ['./introduction.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class IntroductionComponent {
  quizData: Quiz = QUIZ_DATA;
  quizName: String = '';

  constructor(
    private route: ActivatedRoute,
  ) {}

 ngOnInit() {
    this.route.url.subscribe(segments => {
          this.quizName = segments[1].toString();
    });
 }

}

Обновите mat-card *ngIf в introduction.component.html, как показано ниже,

<mat-card *ngIf="quiz.id === quizName">

Это поможет правильно перейти на нужную вводную страницу на основе выбранного теста. Вот StackBlitz

person rinz1er    schedule 13.07.2020