我有嵌套对象,对象的深度可以是N,每个对象都可以有X属性以及嵌套到它的X对象。
问题
1)我无法猜测在整个循环完成之前将哪些列标题添加到我的表中。正如你在第一行中看到的那样,我只有一列“名称”,但在第二行中我有嵌套对象,这些对象为表添加了更多列标题。
2)我想使用jQuery数据表,它不适用于上述场景,因为所有行都没有相同数量的列
3)我不想硬编码任何东西,因为JSON数据可以是任何东西。
这是小提琴:https://jsfiddle.net/jwf347a4/8/
请注意,JSON是动态的,语法将保持不变,但对象和属性的数量+子对象的数量可能会有所不同,因此没有硬编码...谢谢
代码
var resultFromWebService = {
//"odata.metadata": "http://localhost:21088/WcfDataService1.svc/$metadata#Categories&$select=Name,Products,Products/Currency/Symbol",
"value": [{
"Products": [],
"Name": "Meat"
}, {
"Products": [{
"Currency": {
"ID": 47,
"Num": 826,
"Code": "GBP",
"Description": "United Kingdom Pound",
"DigitsAfterDecimal": 2,
"Symbol": "\u00a3",
"Hide": null,
"Priority": 1
},
"ID": 2425,
"Name": "303783",
"ExpiryDate": "2014-02-22T00:00:00",
"CurrencyID": 47,
"Sales": "0.00000000000000000000",
"PreTaxProfitOnProduct": null,
"Assets": "0.30000000000000000000",
"BarCode": null,
"Worth": "0.20000000000000000000",
"MarketValue": null
}],
"Name": "Produce & Vegetable"
}]
};
var createBody = true;
var $table = $('<table id="myTable" class="defaultResultsFormatting"/>');
var $thead = $('<thead />');
var $tbody = $('<tbody />');
var $headRow = $('<tr/>');
var $parentCells = null;
var columnHeaders = [];
$table.append($thead);
var $resultContainer = createResultsTable(resultFromWebService);
$("#resultTableContainer").append($resultContainer);
//$('#myTable').dataTable();
function createResultsTable(data, title) {
if (data) { // && data.length > 0) {
if (createBody) {
$thead.append($headRow);
$table.append($tbody);
createBody = false;
}
if (data.length > 0) {
addColumnHeaders(data[0]);
$.each(data, function(index, e) {
populateTable(e);
});
} else {
addColumnHeaders(data);
populateTable(data);
}
} else {
this.noResults();
}
function addColumnHeaders(result) {
for (var property in result) {
var type = typeof result[property];
if (type === 'string' || type === 'number' || type === 'boolean' || result[property] instanceof Date || !result[property]) {
var mainEntityName = result.__metadata ? result.__metadata.type.split(".").splice(-1)[0] + "." : "";
mainEntityName = (title ? title + "." : mainEntityName);
var cName = mainEntityName + property;
if ($.inArray(cName, columnHeaders) < 0) {
$headRow.append($('<th />', {
text: cName
}));
columnHeaders.push(cName);
console.log("columnHeader:" + cName);
}
}
}
}
function populateTable(data) {
var $bodyRow = null;
if ($parentCells) {
$bodyRow = $parentCells.clone();
} else {
$bodyRow = $('<tr/>');
}
var expandedChildResults = [];
$.each(data, function(index, property) {
var type = typeof property;
if (type === 'string' || type === 'number' || type === 'boolean') {
$bodyRow.append($('<td />', {
text: property
}));
} else if (property instanceof Date) { // DataJS returns the dates as objects and not as strings.
$bodyRow.append($('<td />', {
text: property.toDateString()
}));
} else if (!property) {
$bodyRow.append('<td />');
} else if (typeof property === 'object' && property.results && index !== '__metadata') {
expandedChildResults.push({
key: property.results,
value: index
});
} else if (typeof property === 'object' && index !== '__metadata' && index !== '__deferred' && !isPropertyAnObjectWithJustSingle__deferred(property)) {
expandedChildResults.push({
key: property,
value: index
});
}
});
if (expandedChildResults.length > 0) {
$.each(expandedChildResults, function(index, childObject) {
$parentCells = $bodyRow;
createResultsTable(childObject.key, childObject.value);
});
$parentCells = null;
} else
$tbody.append($bodyRow);
console.log($bodyRow);
}
function isPropertyAnObjectWithJustSingle__deferred(property) {
var keys;
return typeof property === 'object' && // test if it's and object
(keys = Object.keys(property)).length === 1 && // test if it has just sibgle property
keys[0] === '__deferred'; // test if that property is '__deferred'
}
return $table;
};
最大问题/摘要
我遇到的问题是,我不确定在构建整个表对象后如何向行添加空单元格,否则jQuery datable将不喜欢它。
更新
当我有超过1个嵌套的子数组时,当前的答案不起作用等等......
https://jsfiddle.net/1tsu6xt9/46/
正如你所看到的只有一排,我希望它能显示3,就像我在这个小提琴中一样,
答案 0 :(得分:2)
我建议跟踪哪些列已经存在,并使用它来检测何时需要注入新列或跳过未使用的列。
foreach x in ///
"GREEN BLUE" ///
"RED ORANGE" ///
{
replace y = 1 if COLOUR == "`x'" & missing(y)
}
首先,它会使记录变平,以摆脱嵌套。
然后,对于每列,查看该列是否已存在。
如果该列存在,请查看我们是否正在跳过列。如果是这样,我们跳过那么多并插入那么多空单元格。如果没有,我们会记住我们在哪一行,因此我们可以在适当的索引处插入所有先前行中的单元格。
答案 1 :(得分:1)
解决方案( Working Fiddle )构建完表后,调用另一个函数来完成表格将缺少的单元格添加到行中强>
这种逻辑必须有所帮助。
function RestructureTheDynamicTable(){
var $table = $('#myTable');
var maxColumns = $table.find('thead tr th').length; //find the total columns required
$table.find('tbody tr').each(function(){
var thisRowColumnCount = $(this).find('td').length;
var extraTds = "";
if(maxColumns > thisRowColumnCount){ //if this row doesn't have the required number of columns lets add them
for(var i=0;i < maxColumns - thisRowColumnCount;i++){
extraTds += "<td></td>";
}
$(this).append(extraTds);
}
});
}
完成构建表格后调用此函数。表完成重组后,您可以应用Datatables插件