#angular #typescript
#angular #typescript
Вопрос:
У меня есть приложение, в котором пользователь должен ответить на 50 вопросов. Эти вопросы я получаю через веб-сервис, и опубликованные ответы также находятся в веб-сервисе. Я присваиваю эти вопросы номеру билета. Каждые 50 вопросов и опубликованные ответы принадлежат одному билету.
Моя проблема заключается в отображении и сохранении выбора конечного пользователя. Какова наилучшая практика здесь.
Я использую typescript и angular.
Мой текущий подход таков:
Создайте таблицу с 50 записями и выпадающим списком в каждой строке, чтобы ответить на вопрос. Итак, я предварительно выбираю вопросы и показываю выпадающий список.
Моя проблема в том, что я не знаю, как получить доступ к каждой отдельной строке из 50 записей, чтобы определить, были ли на них даны ответы и сохранены.
Я хотел бы сохранить их все сразу (если на все получены ответы) или сохранить их по одному (что не является предпочтительным решением, поскольку это может быть не автономная транзакция? ).
Я попробовал это, используя FormGroup для таблицы. Но это не увенчалось успехом.
Может быть, таблица — это совершенно неправильный подход?
Любая помощь приветствуется! Augeres
Комментарии:
1. Возможно, вы захотите использовать
formArray
Ответ №1:
Этот вопрос имеет много общего с пользовательским интерфейсом и требованиями вашего проекта.
С точки зрения пользователя, если вам нужно ответить на 50 вопросов и щелкнуть по выпадающему списку для каждого из них и подождать, пока соответствующие ответы будут извлечены и нарисованы ниже, вопрос немного болезненный. Лучшим подходом здесь было бы извлечь все вопросы с соответствующими ответами из веб-службы (все в одном http-вызове) и отобразить их только в таблице или любом другом элементе.
Но если пользователь задаст только несколько ответов, ваш подход верен. Вы можете сделать это очень легко в Angular с помощью реактивных форм и FormArray. Я бы сделал это так:
<div *ngFor="let question of questions">
<button (click)="questionsUnfoldedMap[question.id]">Fold/Unfold</button>
<p>{{ question.title }}</p>
<app-related-questions *ngIf="isQuestionUnfolded()"
[relatedAnswers]="relatedAnswersMap[question.id]"
(questionAnswered)="onQuestionAnswered(question.id, $event)">
</app-related-questions>
</div>
Давайте объясним код. Вам нужно будет создать map (просто объект javascript), чтобы знать, какие вопросы свернуты или развернуты (ключом будет идентификатор вопроса, а значением будет просто логическое значение ( questionsUnfoldedMap
в html выше). Каждый раз, когда вы разворачиваете вопрос, вам нужно извлекать данные из веб-службы и сохранять их в другой карте ( relatedAnswersMap
, которая передается RelatedQuestionsComponent
), в которой хранятся ответы на каждый вопрос. Каждый раз, когда пользователь отвечает на вопрос, будет запускаться onQuestionAnswered(questionId, $event)
из вложенного компонента. Все, что вам нужно сделать в этом методе, это просто сохранить идентификатор ответа для идентификатора вопроса в массиве форм и просто отправить его на сервер, когда пользователь отправляет форму.
Наконец, я не знаю, как вам нужно отправлять свои данные в веб-службу, но в этом случае я бы посоветовал вам отправить все данные одним http-вызовом, потому что, если пользователь ответит на все вопросы, вам нужно будет сделать 50 вызовов веб-службы…
Ответ №2:
Большое спасибо за ваш ответ. Я думаю, что лучше всего показывать все 50 вопросов сразу. И есть около 2-5 ответов… в выпадающем списке.
Сейчас я сделал следующее в html:
<div class="row justify-content-center">
<div class="col-8">
<form name="editForm" novalidate (ngSubmit)="submit()" #editForm="ngForm">
<h2 id="jhi--entry-heading">Create or edit a Entry Test</h2>
<div class="table-responsive" *ngIf="Questions">
<table class="table table-striped">
<thead>
<tr jhiSort [(predicate)]="predicate" [(ascending)]="reverse" [callback]="reset.bind(this)">
<th jhiSortBy="id"><span>ID</span>
<fa-icon [icon]="'sort'"></fa-icon>
</th>
<th jhiSortBy="name"><span>Question</span>
<fa-icon [icon]="'sort'"></fa-icon>
</th>
</tr>
</thead>
<tbody infinite-scroll (scrolled)="loadPage(page 1)" [infiniteScrollDisabled]="page >= links['last']" [infiniteScrollDistance]="0">
<tr *ngFor="let Question of Questions ;trackBy: trackId; let i = index;">
<th scope="row">{{Question.id}}</th>
<td>{{Question.name}} {{Question.description}}</br>
<select class="form-control" id="answerid">
<option disabled hidden [value]="selectUndefinedOptionValue">-- select --</option>
<option *ngFor="let answer of Question.answers; let j = index;" [value]="answer.id">{{answer.description}}</option>
</select>
</td>
</tr>
</tbody>
<div>
<button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()">
<fa-icon [icon]="'ban'"></fa-icon>amp;nbsp;<span>Cancel</span>
</button>
<button type="submit" id="save-entity" [disabled]="editForm.form.invalid || isSaving" class="btn btn-primary">
<fa-icon [icon]="'save'"></fa-icon>amp;nbsp;<span>Save</span>
</button>
</div>
</form>
</div>
Эта таблица работает нормально, она предварительно заполняется из сервиса, и вы можете выбрать элемент из выпадающего списка.
Но теперь я полностью потерял, как получить доступ к отдельным записям в таблице из typescript. Я хочу получить доступ к выбранному ответу связанный с ним вопрос. Могу ли я получить полную таблицу как один объект?
Спасибо за вашу помощь! augeres