【发布时间】:2016-09-08 10:08:48
【问题描述】:
我需要从一个一维数组构造一个 html 表,为了抽象起见,它具有以下格式:
{ value: "ABC", colspan: 1, rowspan: 2 }, // etc
还有一个名为width 的属性将是动态的并表示列数。
我相信下面的代码很接近,并且可以处理“非行跨度”数据 - 但我在如何计算单元格跨越时遇到问题,而表格不会超过列数。
我觉得我需要一个“步进器”,每次有行跨度时它都会向上和向下计数,但我无法正确计算数学。
目前,任何行跨度都会导致下一行退出表格的右侧。
基本上我希望它能够将每一个都包裹起来并放在下一个可用的位置。换句话说,动态组装表格。
第 1 轮 - 不工作
http://jsbin.com/zopoxaqato/edit?js,console,output
const input = [
{ value: "a1", colspan: 1, rowspan: 1 },
{ value: "a2", colspan: 1, rowspan: 1 },
{ value: "a3", colspan: 1, rowspan: 3 },
{ value: "b1", colspan: 1, rowspan: 1 },
{ value: "b2", colspan: 1, rowspan: 1 },
{ value: "c1", colspan: 1, rowspan: 1 },
{ value: "c2", colspan: 1, rowspan: 2 },
{ value: "d1", colspan: 1, rowspan: 1 },
{ value: "d3", colspan: 1, rowspan: 1 },
{ value: "e1", colspan: 1, rowspan: 1 },
{ value: "e2", colspan: 2, rowspan: 1 },
];
const width = 3;
const trs = [];
let tds = [];
let rowSpanOffset = 0;
// Loops over entries
input.forEach((cell, index) => {
// Stock standard td
tds.push(`<td colspan="${cell.colspan}" rowspan="${cell.rowspan}">${cell.value}</td>`);
// New row time
if(index % width === width - 1 || rowSpanOffset < 0) {
trs.push("<tr>" + tds.join('') + "</tr>");
// Reset for next row
tds = [];
}
});
const leTable = "<table class='table'>"+trs.join('')+"</table>";
$("body").append(leTable);
第 2 轮 - 改进,但假设输入有效
http://jsbin.com/solesiyuro/edit?js,output
const input = [
{ value: "a1", colspan: 1, rowspan: 1 }, // 1
{ value: "a2", colspan: 1, rowspan: 1 }, // 2
{ value: "a3", colspan: 1, rowspan: 3 }, // 3
{ value: "b1", colspan: 1, rowspan: 1 }, // 1
{ value: "b2", colspan: 1, rowspan: 1 }, // 1
{ value: "c1", colspan: 1, rowspan: 1 }, // 1
{ value: "c2", colspan: 1, rowspan: 2 }, // 2
{ value: "d1", colspan: 1, rowspan: 1 }, // 1
{ value: "d3", colspan: 1, rowspan: 1 }, // 1
{ value: "e1", colspan: 1, rowspan: 1 }, // 1
{ value: "e2", colspan: 1, rowspan: 1 }, // 2
];
const width = 3;
const totalCellCount = _.reduce(input, (sum, c) => sum + c.colspan * c.rowspan, 0);
const grid = _.chunk(_.fill(new Array(totalCellCount), -1), width);
_.each(input, cell => {
let start = [-1, -1];
outerLoop:
for(let y = 0; y < grid.length; y++) {
for(let x = 0; x < width; x++) {
if(grid[y][x] === -1) {
start = [x, y];
break outerLoop;
}
}
}
for(let y = 0; y < cell.rowspan; y++) {
for(let x = 0; x < cell.colspan; x++) {
grid[start[1] + y][start[0] + x] = null;
}
}
grid[start[1]][start[0]] = cell;
});
let trs = [];
let tds = [];
for(let y = 0; y < grid.length; y++) {
for(let x = 0; x < grid[y].length; x++) {
const cell = grid[y][x];
if(cell) {
const value = cell.value;
tds.push('<td colspan="'+cell.colspan+'" rowspan="'+cell.rowspan+'">'+cell.value+'</td>');
}
}
trs.push('<tr>'+tds.join('')+'</tr>');
tds = [];
}
$(".table").append(trs.join(''));
编辑 - 输入错误
错误输入的一个例子是拆分单元格:
const input = [
{ value: "a1", colspan: 1, rowspan: 1 },
{ value: "a2", colspan: 1, rowspan: 2 },
{ value: "a3", colspan: 1, rowspan: 1 },
{ value: "b1", colspan: 3, rowspan: 1 },
];
const width = 3;
【问题讨论】:
-
我在想当输入无效时会发生什么,我想不出能涵盖所有可能情况的东西。我唯一看到的是一条消息或某事说输入无效(可能是原因/在哪里)......您是否希望无效输入被“修复”?如果是这样,输入无效的方式有很多种,每种情况会发生什么?
-
理想情况下,“优雅地”捕获错误是最好的 - 我倾向于在失败的情况下将所有 col/row spans 设置为 1,以便表仍然可用,并显示错误用它。
-
由于您的数据是理想的,因此不太清楚您希望如何处理边缘情况。 IE。如果 a 中的行跨度位于 a2 上,而 colspan 为 2 的位于 b1 上,那么您要做什么?
-
@Chris 所以基本上你的第二个解决方案是可以接受的,如果基本上有一个
ValidateInput函数来检查输入是否有效,即如果有人要添加该函数,这将是你的可接受的答案问题? -
啊,是的,提供者输入是理想的。我现在将添加一个错误输入的示例
标签: javascript jquery html arrays