3

我试图弄清楚如何为selectformArrayName 内部设置绑定对象复杂绑定。我猜测 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使用所有属性(id 和登录名)绑定整个对象
  • 最低附加代码 (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;
  }

4

1 回答 1

2

编辑:根据 OP 的意愿,我们希望将对象保留为选择中的值,因为我们可以代替在 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>

由于我们现在使用对象值作为表单控件,因此在尝试匹配预设值时,我们需要一个 compareWith 函数:

compareFn(a, b): boolean {
  return a.id === b.id;
}

StackBlitz


原始答案:

I would perhaps call a function when the select changes, and then find the user from availableUsersand set the form value for loginwith the found user. 所以模板:

<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

于 2019-02-09T11:03:28.420 回答