首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用JSON数据和变量列填充表

用JSON数据和变量列填充表
EN

Stack Overflow用户
提问于 2018-01-21 01:20:04
回答 3查看 2.4K关注 0票数 0

我有以下JSON数据:

代码语言:javascript
运行
复制
{
    "languageKeys": [{
        "id": 1,
        "project": null,
        "key": "GENERIC.WELCOME",
        "languageStrings": [{
            "id": 1,
            "content": "Welcome",
            "language": {
                "id": 1,
                "key": "EN"
            }
        }]
    }, {
        "id": 2,
        "project": null,
        "key": "GENERIC.HELLO",
        "languageStrings": [{
            "id": 2,
            "content": "Hej",
            "language": {
                "id": 2,
                "key": "DK"
            }
        }, {
            "id": 5,
            "content": "Hello",
            "language": {
                "id": 1,
                "key": "EN"
            }
        }]
    }, {
        "id": 3,
        "project": null,
        "key": "GENERIC.GOODBYE",
        "languageStrings": []
    }]
}

我希望转换成一个表,其中的列是可变的。

表输出应如下所示:

代码语言:javascript
运行
复制
------------------------------------------------
| Key             | EN      | DK  | SE | [...] |
| GENERIC.WELCOME | Welcome |     |    |       |
| GENERIC.HELLO   | Hello   | Hej |    |       |
| GENERIC.GOODBYE |         |     |    |       |
------------------------------------------------

正如您所看到的,该表在行和列中都是动态的,我正在努力弄清楚如何在"EN“、"DK”、"SE“中映射正确的数据……字段添加到正确的列,因为当我从API的JSON响应中获取它们时,它们不一定是按顺序排列的。

到目前为止,我得到了以下呈现函数:

代码语言:javascript
运行
复制
private static renderLanguageKeysTable(languageKeys: ILanguageKey[], languages: ILanguage[]) {
    return <table>
               <thead>
               <tr>
                   <td>Key</td>
                   {languages.map(language =>
                    <td key={language.id}>{language.key}</td>
                )}
               </tr>
               </thead>
               <tbody>
               {languageKeys.map(languageKey =>
                <tr key={languageKey.id}>
                    <td>{languageKey.key}</td>
                    {languages.map(language =>
                        <td key={language.id}>

                        </td>
                    )}
                </tr>
            )}
               </tbody>
           </table>
        ;
}

这是正常工作的,唯一缺少的部分是列中的数据。

我尝试过filtermap的各种变体,但没有一个能达到我想要的效果。

我正在使用ReactJS并用typescript (es2015)书写

澄清一点:列将始终由API定义,行不能具有指向不存在的列的ID,因为它们在后端是相关的。但是,可能会发生某些行没有所有列的情况,在这种情况下,它们应该是空白的

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-01-21 19:22:05

我最终使用了一种与建议不同的方法(在一夜良好的睡眠和一些思考之后)

基本上,我为每个单独的单元格创建了一个新组件,在代码的表格端产生了以下呈现:

代码语言:javascript
运行
复制
private static renderLanguageKeysTable(languageKeys: ILanguageKey[], languages: ILanguage[]) {
    return <table>
               <thead>
               <tr>
                   <th>Key</th>
                   {languages.map(language =>
                    <th key={language.id}>{language.key}</th>
                )}
               </tr>
               </thead>
               <tbody>
               {languageKeys.map(languageKey =>
                <tr key={languageKey.id}>
                    <td>{languageKey.key}</td>
                    {languages.map(language =>
                        <Cell language={language} languageKey={languageKey} key={language.id} />
                    )}
                </tr>
            )}
               </tbody>
           </table>
        ;
}

下面是渲染每个单元格的代码:

代码语言:javascript
运行
复制
import * as React from "react";

export class Cell extends React.Component {
    render() {
        let string: any;
        if (this.props.languageKey && this.props.languageKey.languageStrings) {
            let languageString =
                this.props.languageKey.languageStrings.find((i: any) => i.language.id === this.props.language.id);
            if (languageString === null || languageString === undefined) {
                string = "";
            } else {
                string = languageString.content;
            }
        } else {
            string = "";
        }
        return <td>
            {string}
        </td>;
    }

    props: any;
}
票数 1
EN

Stack Overflow用户

发布于 2018-01-21 02:22:44

代码语言:javascript
运行
复制
const findDistinctLang = (langKeys) => {
  let langString = []
  langKeys.forEach((element) => {
    if(element.languageStrings.length !== 0) {
      langString = [...langString, ...element.languageStrings]
    }
    
  })
 
  const langArr = []

  langString.forEach((element) => {
    if (langArr.indexOf(element.language.key) === -1) {
      langArr.push(element.language.key)
    }
  })
  return langArr
}

class Table extends React.Component {
    state = {
      "languageKeys": [{
        "id": 1,
        "project": null,
        "key": "GENERIC.WELCOME",
        "languageStrings": [{
          "id": 1,
          "content": "Welcome",
          "language": {
            "id": 1,
            "key": "EN"
          }
        }]
      }, {
        "id": 2,
        "project": null,
        "key": "GENERIC.HELLO",
        "languageStrings": [{
          "id": 2,
          "content": "Hej",
          "language": {
            "id": 2,
            "key": "DK"
          }
        }, {
          "id": 5,
          "content": "Hello",
          "language": {
            "id": 1,
            "key": "EN"
          }
        }]
      }, {
        "id": 3,
        "project": null,
        "key": "GENERIC.GOODBYE",
        "languageStrings": [{
          "id": 2,
          "content": "Hej",
          "language": {
            "id": 2,
            "key": "DK"
          }
        },{
          "id": 5,
          "content": "XYZ",
          "language": {
            "id": 7,
            "key": "XYZ"
          }
        }]
      }]
    }
    getContentName = (languageSet, langName) => {
     return _.find(languageSet.languageStrings, function(o) { return o.language.key === langName })
    }
    render() {
      const lanKeyArr = findDistinctLang(this.state.languageKeys)
      return ( <
        table >
        <
        thead >
        <
        tr >
        <
        td > Key < /td> {
          lanKeyArr.map((lang) => {
                return ( < td > {
                    lang
                  } < /td>)
                })
            } <
            /tr> <
            /thead> <
          tbody >
          {
          this.state.languageKeys.map((languageSet) => {
          
          return(
           <tr>
           <td>{languageSet.key}</td>
           {[...lanKeyArr].map((element, index) => {
             const contentObj = this.getContentName(languageSet, element)
             return (
             <td>{contentObj && contentObj.content || ""}</td>
             )
           })
           }
           </tr>
          )
           
          })
          }
            <
            /tbody> < /
            table >

        )
      }
    }
    
    ReactDOM.render(<Table />,document.getElementById("root"))
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

我已经基于你提供的测试数据实现了,注意:你可以让它更干净,通过这个例子给你一个想法

票数 0
EN

Stack Overflow用户

发布于 2018-01-21 03:44:51

您可以解析对象并根据预期的渲染来渲染表。

请注意,没有使用ReactJS的经验,也没有尝试过TypeScript

代码语言:javascript
运行
复制
let languages = {"languageKeys":[{"id":1,"project":null,"key":"GENERIC.WELCOME","languageStrings":[{"id":1,"content":"Welcome","language":{"id":1,"key":"EN"}}]},{"id":2,"project":null,"key":"GENERIC.HELLO","languageStrings":[{"id":2,"content":"Hej","language":{"id":2,"key":"DK"}},{"id":5,"content":"Hello","language":{"id":1,"key":"EN"}}]},{"id":3,"project":null,"key":"GENERIC.GOODBYE","languageStrings":[]}]};

const table = document.querySelector("table");
const thead = table.querySelector("thead").querySelector("tr");
const tbody = table.querySelector("tbody");

Object.values(languages.languageKeys).forEach(({key, languageStrings}) => {
  // check if `languageStrings` array has `.length` greater than `0`
  if (languageStrings.length) {
    languageStrings.forEach(({content, language:{key:lang}}) => {
    console.log(key, content, lang);
    // use block scopes
    { 
      // check if the `lang` is already appended to `<thead>`
      if (![...thead.querySelectorAll("td")].find(({textContent}) => textContent === lang)) {
      let td = document.createElement("td");
      td.textContent = lang;
      thead.appendChild(td);
      }
    }
    {
      // append `key`
      let tr = document.createElement("tr");
      let tdKey = document.createElement("td");
      tdKey.textContent = key;
      tr.appendChild(tdKey);
      // append `content`
      let tdContent = document.createElement("td");
      tdContent.textContent = content;
      tr.appendChild(tdKey);
      tr.appendChild(tdContent);
      tbody.appendChild(tr);      
      // append a `<td>` for placing `<td>` in correct column
      // not an optimal approach, adjust if necessary
      if ([...thead.querySelectorAll("td")].findIndex(el => el.textContent === lang) === tr.children.length) {
        tr.insertBefore(document.createElement("td"), tr.lastElementChild);
      };
    }
   })
  } else { 
      // handle empty `languageStrings` array
      let tr = document.createElement("tr");
      let tdKey = document.createElement("td");
      tdKey.textContent = key;
      tr.appendChild(tdKey);
      tbody.appendChild(tr);
  }
})
代码语言:javascript
运行
复制
<table>
  <thead>
    <tr>
      <td>Key</td>
    </tr>
  </thead>
  <tbody>  
  </tbody>
</table>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48358984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档