【问题标题】:Angular forms - How to bind formControlName for select in formArrayName to use objectsAngular 表单 - 如何绑定 formControlName 以在 formArrayName 中选择以使用对象
【发布时间】:2019-07-03 05:46:42
【问题描述】:

我试图弄清楚如何在 formArrayName 中为select 设置绑定对象复杂绑定。我猜测 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;
  }

【问题讨论】:

    标签: angular angular-reactive-forms formgroups


    【解决方案1】:

    编辑: 根据 OP 的意愿,我们希望将对象保留为选择中的值,因为我们可以在 formarray 中代替使用表单组,只需推送表单控件,然后包含对象价值观:

    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


    原始答案:

    我可能会在选择更改时调用一个函数,然后从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

    【讨论】:

    • 您好,感谢您的解决方案,但我想在不复制更改事件中的数据的情况下将其存档。并不是说如果您设置 ngValue="a" 您已经在 option 中拥有了整个对象,我想重用它。在我的应用程序中,我需要支持一个相当复杂的用户模型,并且我想从一开始就删除所有未来的维护,并为此提供“愚蠢的简单解决方案”。
    • @igby 好吧,我看到的一个选项不是将表单组推送到您的数组,而是表单控件(然后是一个对象)。然后你需要一个compareWith 函数。这是该选项:stackblitz.com/edit/angular-wh3xyg?file=src/app/… 根据具体情况,也许这对您有用?
    • 是的!我正在搜索确切的此类设置。我什至理解我的错误:D 非常感谢!
    • 太好了,很高兴听到它适合您!更新的答案也反映了未来读者的选择:)
    猜你喜欢
    • 2020-02-17
    • 2019-02-07
    • 2017-12-19
    • 2020-01-03
    • 2017-01-28
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多