Angular 5中如何将输入框绑定到Observable对象数组的属性
解决Angular 5动态投注单表单绑定问题
你的问题核心在于单个FormControl无法对应多个投注项的stake属性——当前所有输入框都绑定到同一个stake控件,导致输入内容会互相覆盖,而且无法关联到每个具体的投注对象。要实现每个投注项独立的输入框绑定,你需要使用FormArray来管理一组FormControl,每个控件对应一个投注项的stake值。
下面是修正后的完整代码:
1. 修改 bet-slip.component.ts
import { FormBuilder, FormGroup, FormArray, FormControl } from '@angular/forms'; import { Component, OnInit } from '@angular/core'; import { Bets } from '../../../shared/models'; import { BetService } from '../../../shared/services/bet.service'; import { Observable } from 'rxjs'; @Component({ selector: 'bet-slip', templateUrl: './bet-slip.component.html', styleUrls: ['./bet-slip.component.scss'] }) export class BetSlipComponent implements OnInit { public betSlipItems$: Observable<Bets[]>; public betsForm: FormGroup; constructor( private betService: BetService, private _fb: FormBuilder) { this.betSlipItems$ = this.betService.getBets(); } ngOnInit() { // 初始化表单,包含一个FormArray用于存放所有stake控件 this.betsForm = this._fb.group({ stakes: this._fb.array([]) }); // 订阅投注项数据,同步更新FormArray this.betSlipItems$.subscribe((betSlipItems) => { this.updateStakesFormArray(betSlipItems); }); } // 便捷获取FormArray的方法,模板中会用到 get stakesFormArray(): FormArray { return this.betsForm.get('stakes') as FormArray; } // 根据投注项数组更新FormArray的控件 private updateStakesFormArray(bets: Bets[]) { // 清空现有控件 this.stakesFormArray.clear(); // 为每个投注项创建对应FormControl,初始值为bet.stake bets.forEach(bet => { this.stakesFormArray.push(new FormControl(bet.stake)); }); } // 可选:获取包含最新stake值的完整投注数据 getBetSlipWithStakes(): Bets[] { return this.betSlipItems$.value.map((bet, index) => ({ ...bet, stake: this.stakesFormArray.at(index).value })); } }
2. 修改 bet-slip.component.html
<form [formGroup]="betsForm"> <!-- 绑定FormArray到表单 --> <div formArrayName="stakes"> <!-- 用async pipe直接订阅Observable,省去手动管理订阅 --> <div *ngFor="let bet of betSlipItems$ | async; let i=index"> {{bet.betslipTeamName }} <!-- 绑定到FormArray对应索引的FormControl --> <input type="text" [formControlName]="i"> </div> </div> </form>
关键修改说明:
- 替换单个控件为
FormArray:stakesFormArray会为每个投注项生成独立的FormControl,彻底解决输入互相覆盖的问题。 - 使用
async pipe:模板中直接通过| async订阅Observable,无需手动订阅/取消订阅,避免Angular 5中可能出现的内存泄漏。 - 同步数据与表单:
updateStakesFormArray方法会在投注项数据更新时,同步调整FormArray的控件数量和初始值,保证表单与数据源始终一致。 - 新增便捷getter:
stakesFormArray让组件和模板中访问FormArray更简洁。
如果需要提交表单时获取完整的投注数据(包含用户输入的stake),可以调用getBetSlipWithStakes方法,它会把FormArray中的值映射回原投注对象数组。
内容的提问来源于stack exchange,提问作者Jose the hose
相关产品推荐
相关产品推荐

