You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 10中如何在ngFor循环内获取hidden输入框的值

问题分析与解决方案

核心问题

  1. 数组未匹配初始化:products数组初始为空,当listProduct从服务加载后,数组长度不匹配,Angular无法将product.id绑定到不存在的products[i]索引位置。
  2. 重复表单控件name:所有隐藏输入框和数量输入框使用相同的name属性,导致Angular的ngModel无法正确识别每个独立控件。
  3. 未赋值产品ID:隐藏输入框仅绑定了ngModel,但没有将product.id赋值到绑定变量中。

方案一:修复现有绑定逻辑

1. 修改组件代码,同步初始化数组

在获取产品列表后,初始化products和quantity数组,确保长度匹配并填入初始值:

export class ProductsComponent implements OnInit {
  public listProduct: Product[];
  // 改为public,模板需访问组件属性(Angular默认禁止私有属性绑定)
  public products: number[] = [];
  public quantity: number[] = [];

  constructor(private service: ProductService){}

  ngOnInit(){
    this.service.getProducts().subscribe(
      (listProduct: Product[]) =>{
        this.listProduct = listProduct;
        // 初始化products为每个产品ID,quantity初始为0
        this.products = listProduct.map(product => product.id);
        this.quantity = listProduct.map(() => 0);
      },
      (error) => console.error(error)
    );
  }

  buildCarShopping(){
    console.log("quantity: ", this.quantity);
    console.log("products: ", this.products);
    // 可选:筛选出数量>0的有效购物项
    const cartItems = this.listProduct.map((product, index) => ({
      productId: product.id,
      quantity: this.quantity[index]
    })).filter(item => item.quantity > 0);
    console.log("有效购物项: ", cartItems);
  }
}

2. 修改模板代码,设置唯一控件name

给每个表单控件设置唯一name,确保Angular能正确跟踪控件值:

<form (ngSubmit)="buildCarShopping()">
    <table class="table">
      <thead>
        <tr>
          <th scope="col" class="text-uppercase">stock</th>
          <th scope="col" class="text-uppercase">price</th>
          <th scope="col" class="text-uppercase">quantity</th>
          <th scope="col" class="text-uppercase">buy</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let product of listProduct; let i = index;">
          <!-- 设置唯一name,并绑定product.id到value -->
          <input type="hidden" [name]="'productid-' + i" [(ngModel)]="products[i]" [value]="product.id"/>
          <td class="text-uppercase"> <i class="bi bi-graph-up-arrow m-2 h4"></i>{{product.name}}</td>
          <td class="text-uppercase">$ {{product.price}}</td>
          <td>
            <!-- 设置唯一name,限制输入最小值为0 -->
            <input type="number" class="text-center" [name]="'quantity-' + i" [(ngModel)]="quantity[i]" min="0">
          </td>
          <td>
            <i class="bi bi-cart-check h5" role="button"></i>
          </td>
        </tr>
      </tbody>
    </table>
    <div>
      <button type="submit" class="btn btn-success btn-buy text-uppercase">payment</button>
    </div>
</form>

方案二:更简洁的实现(无需隐藏输入框)

既然已持有listProduct数组,可直接在提交时结合quantity数组关联产品ID,无需额外隐藏输入框:

组件代码(仅优化提交方法)

buildCarShopping(){
  // 直接关联listProduct与quantity数组,生成购物车详情
  const cartItems = this.listProduct.map((product, index) => ({
    productId: product.id,
    productName: product.name,
    price: product.price,
    quantity: this.quantity[index] || 0
  })).filter(item => item.quantity > 0);
  
  console.log("购物车详情: ", cartItems);
  // 此处可将cartItems传递给服务完成后续支付逻辑
}

模板代码(移除隐藏输入框)

<form (ngSubmit)="buildCarShopping()">
    <table class="table">
      <thead>
        <tr>
          <th scope="col" class="text-uppercase">stock</th>
          <th scope="col" class="text-uppercase">price</th>
          <th scope="col" class="text-uppercase">quantity</th>
          <th scope="col" class="text-uppercase">buy</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let product of listProduct; let i = index;">
          <td class="text-uppercase"> <i class="bi bi-graph-up-arrow m-2 h4"></i>{{product.name}}</td>
          <td class="text-uppercase">$ {{product.price}}</td>
          <td>
            <input type="number" class="text-center" [name]="'quantity-' + i" [(ngModel)]="quantity[i]" min="0">
          </td>
          <td>
            <i class="bi bi-cart-check h5" role="button"></i>
          </td>
        </tr>
      </tbody>
    </table>
    <div>
      <button type="submit" class="btn btn-success btn-buy text-uppercase">payment</button>
    </div>
</form>

关键注意点

  • Angular模板默认无法访问组件私有属性,需将products和quantity设为public。
  • 表单控件的name必须唯一,否则ngModel无法正确跟踪每个控件的值。
  • 初始化数组时需与listProduct长度一致,避免索引越界或绑定失效。

内容的提问来源于stack exchange,提问作者gabriel batista

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:30:57