Угловые формы - Как связать 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;
}

StackBlitz


ОРИГИНАЛЬНЫЙ ОТВЕТ:

Возможно, я бы вызвал функцию при изменении выбора, а затем нашел бы пользователя из 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

Другие вопросы по тегам