#angular #typescript #formarray #formgroups
#angular #машинопись #formarray #formgroups
Вопрос:
У меня есть форма для добавления проектов и репозиториев для этих проектов. При добавлении репозитория вы вводите URL-адрес POM. У меня возникли проблемы с доступом к URL-адресам POM, и это мешает загрузке формы.
Я получаю сообщение об ошибке «Не удается прочитать свойство ‘controls’ с нулевым значением
(Код находится на другом компьютере, поэтому я воссоздам его как можно лучше)
TS
this.addProject = new FormGroup({
...
repos: new FormArray([
new FormGroup({
...
pomUrls: new FormArray([new FormControl()])
})
])
});
addRepo(): void {
this.addRepos.push(new FormGroup({
...
pomUrls: new FormArray([new FormControl()])
}));
}
get addRepos(): FormArray {
return this.addProject.get('repos') as FormArray;
}
get pomUrls() {
return this.addRepos.get('pomUrls') as FormArray;
}
addPomUrls() {
const control = new FormControl();
this.pomUrls.push(control);
removePomUrl(index: number): void {
this.pomUrls.removeAt(index);
}
HTML
<ng-container formArrayName="pomUrls">
<div *ngFor="let _ of pomUrls.controls; index as i; count as c;">
<las-ux-textfield [label]="'POM URLs'" [formControlName]="i"></las-ux-textfield>
<div clss="button-container">
<las-ux-button [id]="'addPom' i" ... (click)="addPomUrls()"> </las-ux-button>
<las-ux-button *ngIf="c > 1" [id]="'removePom' i" ... (click)="removePomUrl(i)"> </las-ux-button>
</div>
</div>
</ng-container>
Итак, как есть, это дает мне ошибку «не удается прочитать свойство ‘controls’ с нулевым значением»
Если я изменю get pomUrls на следующее —
get pomUrls() {
return this.addRepos.at(0).get('pomUrls') as FormArray;
— тогда это работает perfectly…at по крайней мере, для извлечения с индексом 0. С помощью этого я могу добавить несколько pomUrls для одного репозитория или добавить несколько репозиториев с одним pomUrl.
НО я не могу добавить несколько репозиториев с несколькими pomUrls. Затем он выдает мне сообщение об ошибке «не удается найти элемент управления с помощью path: ‘repos -> 1 -> pomUrls -> 1′». Таким образом, он не может выйти за пределы индекса 0, что имеет смысл.
Мой вопрос в том, ПОЧЕМУ я не могу заставить это работать? Почему addRepos.at (0).get(‘pomUrls’) работает, а addRepos.get(‘pomUrls’) нет?
Это мой первый большой проект с Angular, и я застрял на этом на неделю. Я искал помощь, формулируя это всеми возможными способами, и прочитал множество статей и других вопросов здесь, в stackoverflow, но безуспешно.
Любая помощь приветствуется!
Ответ №1:
Пожалуйста, добавьте ?
pomUrls?.controls
в свой шаблон html.
pomUrls
не определено в какой-то момент времени выполнения.
?.
является нулевым оператором безопасности
Комментарии:
1. Это устраняет ошибку консоли, но тогда текстовое поле pomUrls не отображается на странице. Есть мысли о том, почему или как это исправить?
Ответ №2:
О проблеме
Самый простой способ понять, как это работает, — визуализировать значение FormGroup
Ниже показано, как FormGroup
addProject
будет выглядеть ваш for
{
repos: [
{
pomUrls: ['']
}
]
}
и это для addRepos
[
{
pomUrls: ['']
}
]
Теперь рассмотрим приведенный ниже код
return this.addRepos.at(0).get('pomUrls') as FormArray;
Приведенный выше код принимает первый элемент ( .at(0)
) и извлекает pomUrls
свойство. В принципе, если бы это был простой JS-код, это было бы myFormGroup[0].pomUrls
. как вы уже упоминали, это работает отлично.
Теперь давайте попробуем этот код
addRepos.get('pomUrls')
Теперь вышесказанное похоже на попытку сделать следующее
const addProject = {
repos: [
{
pomUrls: ['']
}
]
}
const addRepos = addProject.repos;
console.log(addRepos.pomUrls)
Так что, как правило, это похоже на попытку извлечь свойство из массива без получения определенного индекса первым
Как решить?
Вы можете использовать много способов приблизиться к этому. Вы можете рассмотреть ниже
getPomUrls(i) {
return this.addRepos.controls[i].get('pomUrls') as FormArray;
}
В приведенном выше вместо установки pomUrls
в качестве средства получения используйте функцию, которая принимает аргумент индекса
Редактировать 1
Поскольку мы удалили pomUrls
ваше addPomUrls
, вам также придется изменить
addPomUrls(i) {
const control = new FormControl();
this.getPomUrls(i).push(control)
}
По сути, мы добавляем pomUrls для определенного индекса проекта
Комментарии:
1. внесение вышеуказанного изменения останавливает работу addPomUrls() (и removePomUrl(), который я не включил в исходный вопрос). Это больше не работает, потому что свойства ‘push’ (и ‘RemoveAt’) не существуют для типа ‘(i: any) => FormArray’. Есть ли другой способ выполнить мои функции добавления и удаления? Я добавил функцию удаления в свой первоначальный вопрос, чтобы вы тоже могли ее увидеть
2. Спасибо, что добавили, как соответствующим образом изменить addPomUrls. К сожалению, теперь getPomUrls вызывает ошибку «Не удается прочитать свойство ‘get’ неопределенного». Я не могу понять, почему this.addRepos.controls[i] будет считаться неопределенным?