使用JavaScript从JSON值加载HTML表

时间:2019-01-19 19:34:41

标签: javascript html json

我有一个类似https://pastebin.com/ushcMpwY的JSON文件,我想将其加载到具有6列(组,名称,注册1,注册2,星期,半年)的HTML表中。这是我希望它产生的示例:

<table id="people">
    <tr>
        <th>Group name</th>
        <th>Name</th>
        <th>Registration 1</th>
        <th>Registration 2</th>
        <th>Week</th>
        <th>Half term</th>
    </tr>

    <!-- Where JS inserted HTML begins -->
    <tr class="9" id="HA09_000">
        <td>9</td>
        <td>Wyatt Fedlt</td>
        <td>R</td>
        <td>R</td>
        <td>0</td>
        <td>1</td>
    </tr>

    ...

    <!-- Where JS inserted HTML ends -->

</table>

有人建议我应该使用一种https://pastebin.com/0TRrLT6n这样的OOP方法,虽然我能够使它在打印数据方面起作用,但它似乎并不是一种这种方法对于制作实际表格非常有用。目前,这是非常容易的错误。它产生的表看起来像这样:http://prntscr.com/m9eh44,而我只是不知道如何使它成为上面描述的那样,所以我宁愿回到一种我理解的程序方法就像我在下面的伪代码中引用的一样。

最初,我尝试编写一些类似于此伪代码的代码:

TABLE = GET_TABLE_BY_ID('people')
PERSON_COUNT = 0
FOR GROUP IN DATA:
    FOR PERSON IN GROUP:
        ROW = TABLE.INSERTROW(PERSON_COUNT)
        ROW.CLASSLIST.ADD(GROUP.NAME)
        ROW.ID.ADD(PERSON.ID)
        CELL = ROW.INSERTCELL(0)
        CELL.INNERHTML = GROUP.NAME
        INFO_COUNT = 0
        FOR INFO IN PERSON:
            CELL = ROW.INSERTCELL(INFO_COUNT)
            CELL.INNERHTML = INFO
            INFO_COUNT++
        PERSON_COUNT++

这导致了一些实际的代码(当时我只是想打印出这些值,因为那样就足够简单了,可以将其转换为代码以生成表)。

$.getJSON("http://localhost:8000/data.json", function(data) {
    output_json(data);
});

function output_json(data) {
    var i, j, k;
    for (i = 0; i < Object.keys(data).length; i++) {
        group_ = Object.values(data)[i];
        for (j = 0; j < Object.keys(group_).length; j++) {
            person = Object.values(group_)[j];
            person_id = Object.keys(person)[0];
            console.log(Object.keys(data)[i]); // Group
            console.log(person_id); // ID
            for (k = 0; k < Object.keys(person).length; k++) {
                person_info = Object.values(person)[k][0];
                console.log(person_info); // Information
            }
        }
    }
}

我希望这段代码为每个人打印出我想输入到表中的数据,即他们的小组,他们的姓名等。我希望这样做:

  

9

     

HA09_000

     

怀亚特·费尔德特

     

R

     

R

     

0

     

1

但是,我的代码当前产生的是:

  

9

     

HA09_000

     

{名称:“怀亚特·费尔德(Wyatt Feldt)”,注册_1:“ R”,注册_2:“ R”,周:0,半学期:1}

如果有人可以告诉我至少如何打印值(只要是过程性的),我相信我可以在自己中添加表格部分。但是,如果您认为这确实应该是OOP,那么如果您能向我解释我也可以如何实现表部分,我将不胜感激。我知道我可以使用4个for循环来完成这项工作,但这效率很低,而且我相信它可以在3个更清晰的循环中完成,就像我在伪代码中列出的那样。

谢谢。

2 个答案:

答案 0 :(得分:1)

IMO更具可读性/优雅的解决方案是将关注点稍微分开,并使用纯函数...

  1. 整理所有数据
  2. 构建HTML表格行
  3. 添加到表格
    let rowKeys = Object.keys(data);

    // iterate over the 'first level' keys with the goal of extracting the values needed in the final objects (elemClass), while then extracting the 'second level' object (group) so that you can access its data.
    let rowsFlattened = rowKeys.reduce((acc,key) => {
            let elemClass = key,
                group = data[key];

             let people = group.reduce((acc2,groupObj)=> {
                    let elemId = Object.keys(groupObj)[0],
                        person = groupObj[elemId][0];

                        return [
                            ...acc2,
                            {
                                ...person,
                                className: elemClass,
                                id: elemId
                            }
                        ]
                },[])

                // these 'spread operators' merge either objects or arrays, in this case an array.
                return [
                    ...acc,
                    ...people
                ]

        // this '[]' is the starting accumulator, which you have access to in the 'acc' parameter above. After each iteration this 'acc' value is replaced by whatever value is returned in the previous iteration. 
        },[]);

    // 
    let rowsHTML = rowsFlattened.map(obj => {
            let { className, id, name, registration_1, registration_2, week, half_term} = obj;
            return `
                <tr class="${className}" id="${id}">
                    <td>${className}</td>
                    <td>${name}</td>
                    <td>${registration_1}</td>
                    <td>${registration_2}</td>
                    <td>${week}</td>
                    <td>${half_term}</td>
                </tr>
            `
        })  

        $('#people').html(rowsHTML);

我的解决方案有点长,所以请参见下面的jsFiddle ...

https://jsfiddle.net/u1ekga7y/

答案 1 :(得分:0)

我猜您希望该人员信息位于数组中?添加另一个循环以遍历person_info对象的键和值。

        for (k = 0; k < Object.keys(person).length; k++) {
            person_info = Object.values(person)[k][0];
            console.log(person_info); // Information
        }

收件人

        var person_info_data = [];
        for (k = 0; k < Object.keys(person).length; k++) {
            person_info = Object.values(person)[k][0];
            for (l = 0; l < Object.keys(person_info).length; l++) {
                person_info_data.push(Object.values(person_info)[l])
            }
            console.log(person_info_data); // Information
        }