#angular #angular7 #angular-reactive-forms #dynamic-forms #form-control
#угловатый #угловой 7 #угловые реактивные формы #динамические формы #управление формой
Вопрос:
Я работаю над динамической формой в angular 7. Я следовал пути, который упоминается на официальном сайте angular. Я успешно реализовал этот учебник, но мой сценарий отличается. какой тип ввода будет присутствовать в форме, и все его атрибуты будут получены из ответа API
это функция в сервисе, которая приносит мои данные. Пожалуйста, обратите внимание: на основе данных API я заполню свой массив вопросов, а пока я использовал фиктивные данные только для того, чтобы убедиться, что поток работает. вот как выглядит мой вопрос.service.ts выглядит так
public response : QuestionBase<any>[] =[];
getQuestions(id) {
this.http.get(this.url 'selectAllFieldDetails/' id)
.pipe(map(
( response: Response) => {
let data = response;
console.log(data);
let questions: QuestionBase<any>[] = [
new DropdownQuestion({
key: 'brave',
label: 'Bravery Ratings',
class:'form-control fis-form-control',
formclass:'',
options: [
{key: 'solid', value: 'Solid'},
{key: 'great', value: 'Great'},
{key: 'good', value: 'Good'},
{key: 'unproven', value: 'Unproven'}
],
required: true,
order: 2
}),
new TextboxQuestion({
key: 'process',
label: 'Process name',
value: 'IT ',
class:'form-control fis-form-control',
formclass:'',
required: true,
order: 1
}),
];
this.response = questions.sort((a, b) => a.order - b.order);
}
));
console.log(this.response);
return this.response;
}
Но проблема заключается в возврате функции перед ответом API, и она возвращает пустой массив. Именно так я звоню из create-ticket.component.ts
ngOnInit() {
this.questions = this.service.getQuestions(24);
console.log(this.questions);
}
Каким-то образом я попытался сначала получить ответ API и сохранить его в некоторой переменной, а затем вызвать эту функцию this.service.getQuestions(24); но затем он показывает ошибку, которая
Error: Cannot find control with name: 'process'
at _throwError (forms.js:1775)
at setUpControl (forms.js:1683)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addControl (forms.js:4532)
at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName._setUpControl (forms.js:5030)
at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName.ngOnChanges (forms.js:4980)
at checkAndUpdateDirectiveInline (core.js:9239)
at checkAndUpdateNodeInline (core.js:10507)
at checkAndUpdateNode (core.js:10469)
at debugCheckAndUpdateNode (core.js:11102)
at debugCheckDirectivesFn (core.js:11062)
и данные Formgorup остаются пустыми.
Пожалуйста, помогите мне в этой проблеме.
Заранее спасибо
Комментарии:
1. пожалуйста, предоставьте весь код или, что еще лучше, stackblitz для минимального устранения неполадок.
2. и проблема в том, что вы не подписываетесь на запрос get, чтобы выполнить запрос.
Ответ №1:
Итак, наконец, после долгих исследований и разработок я это сделал. в основном было две проблемы
- функция в сервисе отвечает перед ответом API
- форма создается до того, как данные поступают в бизнес
Итак, для первого выпуска я использовал концепцию async await
функции в angular
В create-ticket.component.ts мы добавили асинхронность и ожидание, подобные этому.
async ngOnInit() {
this.questions = await this.service.getQuestionss(24);
if(this.questions.length>0){
this.showForm=true;
}
}
и в сервисе мы возвращаем обещание
async getQuestionss(id): Promise<any> {
this.responses = await this.apiServce.getAllInputFields(id).toPromise();
}
он отвечает как обещание, поэтому он ожидает ответа api. this.apiservice.getAllInputFields(id)
это просто вызов http api с сервера.
Для 2-й проблемы я использовал только небольшое решение. я добавил *ngIf в форму, поэтому, когда api отвечает данными, тогда только форма начинает строиться.
<app-dynamic-forms *ngIf="showForm" [questions]="questions"></app-dynamic-forms>
Вот и все, и проблема решена.
Ответ №2:
устаревшая информация, основанная на stackblitz
Вы должны всегда подписываться на асинхронный вызов, чтобы он выполнялся
ngOnInit() { this.questions = this.service.getQuestions(24).subscribe(result => { do something with result }, err => { something went wrong }); }
Вот stackblitz, основанный на вашем :
https://stackblitz.com/edit/angular-h8zakj?embed=1amp;file=src/app/question .сервис.ts
как я уже сказал, возникла проблема с вашим setTimeout. данные были недоступны там, где вы этого хотели.
Комментарии:
1. свойство subscribe не существует для типа QuestionBase<any>[]. это мой интерфейс questionbase. экспортировать класс QuestionBase<T> { значение: T; ключ: строка; метка: строка; требуется: логическое значение; порядок: число; класс: строка; ControlType: строка; formclass: строка; конструктор(параметры: { значение?: T, ключ?: строка, метка?: строка, обязательно?: логическое значение, порядок?: номер, класс?: строка, формкласс?: строка, тип элемента управления?: строка } = {}) { } }
2. да, он должен вернуть вызов thiis.http.get как наблюдаемый из своего сервиса и изменить возвращаемый тип. в любом случае, он смешал много неполного материала. вот почему я запросил код режима
3. вы можете увидеть здесь angular.io/generated/live-examples/dynamic-form/stackblitz.html
4. в конце он должен вернуться
getQuestions(id) { this.http.get(this.url 'selectAllFieldDetails/' id) .pipe(map( ...
как наблюдаемый. на данный момент ему нужно повторно использовать наблюдаемую часть своих фиктивных данных, чтобы заставить это работать5. stackblitz.com/edit/angular-ytkydp это URL-адрес редактора. вы можете видеть проблему, с которой я столкнулся. Я вызвал функцию settimeout вместо http-вызова, потому что поведение такое же. если вы удалите функцию settimeout, появится форма.