如何使用Alpine.js的x-for独立设置嵌套表格的单元格值
问题根因
你当前所有行的数据都共享根级别的fields和fields1数组,每次新增行时还会先清空这两个数组,导致所有行绑定的都是同一份数据源,自然会出现修改一行所有行同步变更的问题。正确的做法是把每行专属的fields、fields1数据存到对应的rows数组的每一项里,每行独立持有自己的数据源,互不干扰。
修正后的JS代码
function handler() { return { rows: [], // 初始化行ID计数 id: 1, addRate(row) { row.fields1.push({ value1: '', value2: '', value3: '', rType: '', typeA: '', value4: '', typeBDateFrom: '', typeBDateTo: '' }); }, listField() { // 每次新增行,创建独立的fields和fields1挂载到当前行对象 const newRow = { id: this.id++, fields1: [], fields: [] }; // 给当前新行初始化fields1数据 newRow.fields1.push({ value1: '', value2: '', value3: '', rType: '', typeA: '', value4: '', typeBDateFrom: '', typeBDateTo: '' }); // 给当前新行初始化fields数据 newRow.fields.push({ value5: '3', value6: '20', value7: 'DC', value8: '40', value9: '523', value10: '654', value11: 'TEST', value12: 'true', value13: 'Class1', value14: '5656', value15: 'TRM78799', id:'1' }); this.rows.push(newRow); }, } }; function setDecimal(event) { event.target.value = parseFloat(event.target.value).toFixed(3); };
修正后的HTML代码
仅需要把原来遍历全局fields1和fields的逻辑,改为从当前遍历的行对象中取对应数据即可,同时修复了原有HTML不符合表格规范、输入框类型错误等问题:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> <div class="container col-md-10 offset-md-1"> <div class="row" x-data="handler()" x-init="listField()"> <div class="col"> <table class="table align-items-center table-sm" style="text-align: center;"> <tr> <template x-for="(row, rowIndex) in rows" :key="row.id"> <td colspan="12"> <p> <table class="table align-items-center table-sm table-bordered" style="text-align: center;"> <tbody> <!-- 从当前行对象取独立的fields1 --> <template x-for="(field1, index) in row.fields1" :key="index"> <tr class="table-success"> <td style="width:100px;"><b>Type</b></td> <td style="width:100px;"> <select x-model="field1.rType" class="custom-select" name="rType" required> <option selected>---</option> <option value="Type A">Type A</option> <option value="Type B">Type B</option> </select> </td> <td x-show="field1.rType==='Type A'" style="width:120px;"> <b>Type A Name</b> </td> <td x-show="field1.rType==='Type A'"> <input x-model="field1.typeA" type="text" class="form-control" name="typeA"> </td> <td x-show="field1.rType==='Type A'" style="width:150px;"> <b>Value4</b> </td> <td x-show="field1.rType==='Type A'"> <input x-model="field1.value4" type="text" class="form-control" name="value4"> </td> <td x-show="field1.rType==='Type B'" style="width:120px;"> <b>From</b> </td> <td x-show="field1.rType==='Type B'"> <input x-model="field1.typeBDateFrom" type="date" class="form-control" name="typeBDateFrom"> </td> <td x-show="field1.rType==='Type B'" style="width:150px;"> <b>To</b> </td> <td x-show="field1.rType==='Type B'"> <input x-model="field1.typeBDateTo" type="date" class="form-control" name="typeBDateTo"> </td> </tr> </template> </tbody> </table> </p> <p> <table class="table align-items-center table-sm table-bordered" style="text-align: center;"> <thead class="thead-dark"> <tr> <th>No</th> <th style="width:20px;">Value5</th> <th style="width:80px;">Value6</th> <th style="width:150px;">Value7</th> <th style="width:120px;">Value8</th> <th style="width:120px;">Value9</th> <th style="width:130px;">Value11</th> <th style="width:180px;">Value12</th> <th style="width:180px;">Value1</th> <th style="width:180px;">Value2</th> <th style="width:180px;">Value3</th> </tr> </thead> <tbody> <!-- 从当前行对象取独立的fields --> <template x-for="(field, index) in row.fields" :key="index"> <tr> <td x-text="index + 1"></td> <td x-text="field.value5"></td> <td x-text="field.value6"></td> <td> <p x-text="field.value7"></p> <p x-show="field.value7==='RFR' || field.value7==='RFRHC'"> <span x-text="field.value8"></span><span>℃</span> </p> </td> <td x-text="field.value9"></td> <td x-text="field.value10"></td> <td x-text="field.value11"></td> <td x-show="field.value12"> <p> <label><b>Value13 </b><span x-text="field.value13"></span></label> </p> <p> <label><b>Value14 </b><span x-text="field.value14"></span></label> </p> </td> <td x-show="!field.value12"></td> <td class="table-success"> <input x-model="field.value1" type="number" class="form-control" @change="setDecimal" min="0" max="10000000" name="value1" step="0.001" value="0.000" required> </td> <td class="table-success"> <select x-model="field.value2" class="custom-select" name="value2" required> <option selected>---</option> <option value="USD">USD</option> <option value="EUR">EUR</option> </select> </td> <td class="table-success"> <input x-model="field.value3" type="text" class="form-control" name="value3"> </td> </tr> </template> </tbody> </table> </p> </td> </template> </tr> <tr> <td colspan="12" class="text-right"><button type="button" class="btn btn-info" @click="listField()">+ Add Row</button></td> </tr> </table> </div> </div> </div> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js" defer></script>
其他附带修正
- 修复了
setDecimal函数的指向问题,原写法拿不到正确的输入框元素 - 修正了原HTML里
type="Type B"的错误输入框类型,改为标准的date类型 - 修正了条件判断里的单竖线
|为逻辑或|| - 移除了重复的id属性,避免DOM id冲突
- 行的key改为唯一的
row.id,避免列表渲染异常 - 原
<template>外层直接包<p>不符合table结构,改为套<td colspan="12">符合HTML表格规范
内容的提问来源于stack exchange,提问作者Cem F. Çelebi
相关产品推荐
相关产品推荐

