Угловые формы - Как связать formControlName для выбора в formArrayName для использования объектов
Я пытаюсь выяснить, как установить сложную привязку объекта привязки для select
внутри formArrayName. Я предполагаю, что formControlName должен иметь ссылку на текущий элемент в массиве, но я не знаю, как получить к нему доступ.
<div formArrayName="users">
<div *ngFor="let u of users.controls; let i=index" [formGroupName]='i'>
user {{i}}: <select formControlName='id'[compareWith]="compareFn">
<option *ngFor="let a of avaliableUsers" [ngValue]='a'>{{a.login}}</option>
</select>
</div>
</div>
Я создал демо с единственным выбором (который работает, как я хочу) и массивом, который помещает значение в "id". https://stackblitz.com/edit/angular-d2uaa1
Любая помощь с благодарностью.
РЕДАКТИРОВАТЬ
Ключевые моменты:
- Связать весь
UsersGroup
объекты со всеми свойствами (идентификатор и логин) - Минимальный дополнительный код (KISS)
Решение (на основе комментария @JT_82)
<div *ngFor="let u of users.controls; let i=index">
<select [formControlName]='i' [compareWith]="compareFn">
<option *ngFor="let a of avaliableUsers" [ngValue]='a'>{{a.login}}</option>
</select>
</div>
ngOnInit(): void {
this.owner.patchValue(this.group.owner);
this.group.users.forEach(u => {
this.users.push(this.fb.control(u))
});
}
compareFn(a, b): boolean {
return a.id === b.id;
}
1 ответ
РЕДАКТИРОВАТЬ: В соответствии с пожеланиями OP, мы хотели бы сохранить объект в качестве значения в select, для этого мы можем вместо использования группы форм внутри formarray, просто нажать formcontrols, который затем содержит значения объекта:
this.group.users.forEach(u => {
this.users.push(this.fb.control(u)) // just push formcontrol!
});
а затем отметьте в шаблоне:
<select [formControlName]='i' [compareWith]="compareFn">
<option *ngFor="let a of avaliableUsers" [ngValue]='a'>{{a.login}}</option>
</select>
Поскольку теперь мы используем значение объекта в качестве formcontrol, при попытке сопоставления с предустановленными значениями нам нужна функция compareWith:
compareFn(a, b): boolean {
return a.id === b.id;
}
ОРИГИНАЛЬНЫЙ ОТВЕТ:
Возможно, я бы вызвал функцию при изменении выбора, а затем нашел бы пользователя из availableUsers
и установите значение формы для login
с найденным пользователем. Итак шаблон:
<select formControlName='id' (change)="findLogin(u)">
<option *ngFor="let a of avaliableUsers" [ngValue]='a.id'>{{a.login}}</option>
</select>
Так что вы можете удалить compareWith
, поскольку мы сейчас используем число для значения. Тогда findLogin
функция, в которой мы передаем текущую форму группы из итерации:
findLogin(group: FormGroup) {
const user = this.avaliableUsers.find(x => x.id === group.get('id').value)
group.get('login').setValue(user.login);
}
Ваш раздвоенный StackBlitz