Javascript 嵌套数组到平面表的叉积
我有嵌套对象,对象的深度可以是N,每个对象可以有X个属性以及嵌套到其中的X个对象 问题 1) 在整个循环完成之前,我很难猜测哪些列标题将添加到表中。正如您在我的第一行中所看到的,我只有一列“Name”,但在第二行中,我有嵌套的对象,这些对象向表中添加了更多的列标题 2) 我想让它与jQuery datatable一起工作,而jQuery datatable不适用于上述场景,因为所有行的列数都不相同 3) 我不想硬编码任何东西,因为JSON数据可以是任何东西 这是小提琴: 请注意,JSON是动态的,语法将保持不变,但对象和属性的数量+子对象的数量可能会有所不同,因此没有硬编码。。。谢谢 代码Javascript 嵌套数组到平面表的叉积,javascript,jquery,html,datatables,Javascript,Jquery,Html,Datatables,我有嵌套对象,对象的深度可以是N,每个对象可以有X个属性以及嵌套到其中的X个对象 问题 1) 在整个循环完成之前,我很难猜测哪些列标题将添加到表中。正如您在我的第一行中所看到的,我只有一列“Name”,但在第二行中,我有嵌套的对象,这些对象向表中添加了更多的列标题 2) 我想让它与jQuery datatable一起工作,而jQuery datatable不适用于上述场景,因为所有行的列数都不相同 3) 我不想硬编码任何东西,因为JSON数据可以是任何东西 这是小提琴: 请注意,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;
};
var resultFromWebService={
//“odata.metadata”:”http://localhost:21088/WcfDataService1.svc/$metadata#类别&$select=名称、产品、产品/货币/符号“,
“价值”:[{
“产品”:[],
“名称”:“肉”
}, {
“产品”:[{
“货币”:{
“ID”:47,
“Num”:826,
“代码”:“英镑”,
“说明”:“英国镑”,
“数字后十进制”:2,
“符号”:“\u00a3”,
“隐藏”:空,
“优先权”:1
},
“ID”:2425,
“名称”:“303783”,
“到期日”:“2014-02-22T00:00:00”,
“CurrencyID”:47,
“销售”:“0.00000000000000”,
“PreTaxProfitOnProduct”:空,
“资产”:“300000000000000000000”,
“条形码”:空,
“价值”:“0.200000000000000000000”,
“市场价值”:空
}],
“名称”:“农产品和蔬菜”
}]
};
var createBody=true;
变量$table=$('');
变量$thead=$('');
变量$tbody=$('');
var$水头=$('');
var$parentCells=null;
var columnHeaders=[];
$table.append($thead);
var$resultContainer=createResultsTable(resultFromWebService);
$(“#resultablecontainer”).append($resultContainer);
//$('#myTable').dataTable();
函数createResultsTable(数据、标题){
如果(数据){/&&data.length>0){
if(createBody){
$thead.append($headlow);
$table.append($tbody);
createBody=false;
}
如果(data.length>0){
addColumnHeader(数据[0]);
$。每个(数据,函数(索引,e){
可推广(e);
});
}否则{
添加列标题(数据);
可普及(数据);
}
}否则{
这个。noResults();
}
函数addColumnHeaders(结果){
for(结果中的var属性){
变量类型=结果的类型[属性];
如果(类型=='string'| |类型=='number'| |类型=='boolean'| | |结果[属性]日期实例| |!结果[属性]){
var maintentityname=result.\uuuuu元数据?result.\uuuu元数据.type.split(“.”)splice(-1)[0]+“:”;
mainEntityName=(标题?标题+”:mainEntityName);
var cName=maintentityname+属性;
if($.inArray(cName,ColumnHeader)<0){
$headlow.append($(''){
文本:cName
}));
columnHeaders.push(cName);
console.log(“columnHeader:+cName”);
}
}
}
}
函数populateTable(数据){
var$bodyRow=null;
如果($parentCells){
$bodyRow=$parentCells.clone();
}否则{
$bodyRow=$('');
}
var expandedChildResults=[];
$.each(数据、函数(索引、属性){
var类型=属性的类型;
如果(类型=='string'| |类型=='number'| |类型=='boolean'){
$bodyRow.append($(''){
文本:属性
}));
}else if(property instanceof Date){//DataJS将日期作为对象而不是字符串返回。
$bodyRow.append($(''){
text:property.toDateString()
}));
}如果(!属性){
$bodyRow.append(“”);
}else if(typeof property==='object'&&property.results&&index!=='uuu元数据'){
expandedChildResults.push({
关键字:property.results,
值:索引
});
}else if(typeof property==='object'&&index!='\uuu metadata'&&index!='\uu deferred'&&&!isPropertyAnObjectWithJustSingle\uu deferred(property)){
expandedChildResults.push({
关键:财产,
值:索引
});
}
});
如果(expandedChildResults.length>0){
$.each(展开的ChildResults,函数(索引,childObject){
$parentCells=$bodyRow;
createResultsTable(childObject.key,childObject.value);
});
$parentCells=null;
}否则
$tbody.append($bodyRow);
console.log($bodyRow);
}
函数isPropertyAnObjectWithJustSingle__;deferred(属性){
var键;
返回typeof属性==='object'&&&//测试它是否为和对象
(keys=Object.keys(property)).length==1&&//测试它是否只有sible属性
键[0]=='\uu deferred';//测试该属性是否为'\uu deferred'
}
返回$table;
};
最大的问题/总结
我遇到的问题是,一旦构建了整个表对象,我不确定如何将空单元格添加到行中,否则jquerydatable将不喜欢它
更新
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;
};
当我有超过1个嵌套的子数组时,当前的答案不起作用,以此类推
正如你所看到的,只有一行,我希望它显示3行,就像我在这把小提琴中看到的一样
解决方案:()一旦您构建了表格,请调用另一个函数,该函数将通过向行中添加缺少的单元格来完成表格 这一逻辑必须有所帮助
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);
}
});
}
函数重构动态表(){
var$table=$(“#myTable”);
var maxColumns=$table.find('thead tr th').length;//查找所需的总列数
$table.find('tbody tr')。每个(函数(){
var thisRowColumnCount=$(this).find('td').length;
var extraTds=