【问题标题】:Show a pop-up window with information coming from an element and its totals, from one of the table in react.js显示一个弹出窗口,其中包含来自 react.js 中的一个表的元素及其总数的信息
【发布时间】:2021-03-31 01:57:46
【问题描述】:

我正在用 React.Js 开发一个应用程序。

我有数组:

array = [
  {
    "id": 1,
    "date": {
      "id": 1,
      "name": "202001"
    },
    "item": {
      "id": 1,
      "name": "I1"
    },
    "price": 100
    },
    {
    "id": 2,
    "date": {
      "id": 2,
      "name": "202002"
    },
    "item": {
      "id": 1,
      "name": "I1"
    },
    "price": 200
  },
  {
    "id": 3,
    "date": {
      "id": 2,
      "name": "202002"
    },
    "item": {
      "id": 2,
      "name": "I2"
    },
    "price": 300
  },
]

而我显示的数据如表所示:

ITEM 202001 202002 TOTAL
I1 100 200 300
I2 - 300 300
TOTAL 100 500 600

我这样做是为了获得这些值:

items_dicc = array.reduce((acc, e) => {
    if (!acc[e["item"]["name"]]) {
      acc[e["item"]["name"]] = {
        [e["date"]["name"]]: e["price"]
      }
    } else {
      acc[e["item"]["name"]][e["date"]["name"]] = e["price"]
    }
    return acc
  }, {})

dates = [...new Set(Object.keys(items_dicc).map(i => Object.keys(items_dicc[i])).flat())]

totalSumPerDate = {};

dates.forEach(date => {
  const sumOnDate = Object.values(items_dicc).reduce((acc, curr) => {
    acc = acc + (curr[date]? curr[date] : 0);
    return acc;
  }, 0);
  totalSumPerDate[[date]] = sumOnDate;
});

totalSum = Object.values(totalSumPerDate).reduce((acc, curr) => acc+curr, 0);

sumPerItem = {};

Object.keys(items_dicc).forEach(key => {
   const sum = Object.values(items_dicc[key]).reduce((acc, curr) => acc + curr, 0);
   sumPerItem[[key]] = sum;
});


<table>
  <thead>
    <tr>
      <th>ITEM</th>
      {dates.map(date => <th>{date}</th>)}
      <th>TOTAL</th>
    </tr>
  </thead>
  <tbody>
  {
    Object.keys(items_dicc).map((item) => {
      return (
        <tr>
          <td>{item}</td>
          {dates.map((date) => <td>{items_dicc[item][date] || ''}</td>)}
          <td>{sumPerItem[item]}</td>
        </tr>
      )
    })
  }
    <tr>
      <td>TOTAL</td>
        {Object.values(totalSumPerDate).map(item => <td>{item}</td>)}
      <td>{totalSum}</td>
    </tr>
  </tbody>
</table>

我需要能够通过弹出窗口显示数组可能包含的其他数据(例如 id)。

我知道要做到这一点,有必要在组件中创建一个本地状态,以便在单击所选记录时更新详细信息并将状态传递给模式。

它还应该能够引入总计信息。

我该怎么做,建议?

【问题讨论】:

    标签: javascript arrays json reactjs popup


    【解决方案1】:

    您可以像这样将总数据传递给 onClickEventHandler,

        <tr onClick={(event) => yourHandler(event, item, sumPerItem[item])}>
          <td>{item}</td>
          {dates.map((date) => <td>{items_dicc[item][date] || ''}</td>)}
          <td>{sumPerItem[item]}</td>
        </tr>
    

    事件处理程序应该这样写,

    yourHandler = (event, currentItem, totalForRow) => {
        // You update the state here 
    }
    

    此方法适用于整行。如果您想在每个单元格上显示不同的数据,您需要在元素上添加 eventHandler 并根据需要更新方法参数。

    【讨论】:

    • 我会尝试实现它,稍后我会告诉你。感谢您的帮助!
    • 你好@sabbir.alam!你能详细说明一下你解决它的方法吗?谢谢!
    【解决方案2】:

    试试这个方法,

    您必须为表格行的选定记录创建本地状态并将其传递给模态组件。单击表格行时更新所选记录。

    import React, { useState } from "react";
    import "./styles.css";
    import "bootstrap/dist/css/bootstrap.min.css";
    
    const array = [
      {
        id: 1,
        date: {
          id: 1,
          name: "202001"
        },
        item: {
          id: 1,
          name: "I1"
        },
        price: 100
      },
      {
        id: 2,
        date: {
          id: 2,
          name: "202002"
        },
        item: {
          id: 1,
          name: "I1"
        },
        price: 200
      },
      {
        id: 3,
        date: {
          id: 2,
          name: "202002"
        },
        item: {
          id: 2,
          name: "I2"
        },
        price: 300
      }
    ];
    
    export default function App() {
      const [show, setShow] = useState(false);
      const [selectedData, setSelectedData] = useState({});
      const hanldeClick = (selectedId) => {
        const selectedRec = array.find((val) => val.item.name === selectedId);
        setSelectedData(selectedRec);
        setShow(true);
      };
    
      const hideModal = () => {
        setShow(false);
      };
      const items_dicc = array.reduce((acc, e) => {
        if (!acc[e["item"]["name"]]) {
          acc[e["item"]["name"]] = {
            [e["date"]["name"]]: e["price"]
          };
        } else {
          acc[e["item"]["name"]][e["date"]["name"]] = e["price"];
        }
        return acc;
      }, {});
    
      const dates = [
        ...new Set(
          Object.keys(items_dicc)
            .map((i) => Object.keys(items_dicc[i]))
            .flat()
        )
      ];
    
      const totalSumPerDate = {};
    
      dates.forEach((date) => {
        const sumOnDate = Object.values(items_dicc).reduce((acc, curr) => {
          acc = acc + (curr[date] ? curr[date] : 0);
          return acc;
        }, 0);
        totalSumPerDate[[date]] = sumOnDate;
      });
    
      const totalSum = Object.values(totalSumPerDate).reduce(
        (acc, curr) => acc + curr,
        0
      );
    
      const sumPerItem = {};
    
      Object.keys(items_dicc).forEach((key) => {
        const sum = Object.values(items_dicc[key]).reduce(
          (acc, curr) => acc + curr,
          0
        );
        sumPerItem[[key]] = sum;
      });
    
      return (
        <>
          <table>
            <thead>
              <tr>
                <th>ITEM</th>
                {dates.map((date) => (
                  <th>{date}</th>
                ))}
                <th>TOTAL</th>
              </tr>
            </thead>
            <tbody>
              {Object.keys(items_dicc).map((item) => {
                return (
                  <tr onClick={() => hanldeClick(item)}>
                    <td>{item}</td>
                    {dates.map((date) => (
                      <td>{items_dicc[item][date] || ""}</td>
                    ))}
                    <td>{sumPerItem[item]}</td>
                  </tr>
                );
              })}
              <tr>
                <td>TOTAL</td>
                {Object.values(totalSumPerDate).map((item) => (
                  <td>{item}</td>
                ))}
                <td>{totalSum}</td>
              </tr>
            </tbody>
          </table>
          {show && <Modal details={selectedData} handleClose={hideModal} />}
        </>
      );
    }
    
    const Modal = ({ handleClose, details }) => {
      console.log(details);
      return (
        <div className="modal display-block">
          <section className="modal-main">
            <div className="App">
              <table class="table">
                <thead>
                  <tr>
                    <th scope="col">ITEM</th>
                    <th scope="col">ID</th>
                    <th scope="col">DATE</th>
                    <th scope="col">PRICE</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td>{details?.item?.name}</td>
                    <td>{details?.item?.id}</td>
                    <td>{details?.date?.name}</td>
                    <td>{details?.price}</td>
                  </tr>
                </tbody>
              </table>
            </div>
            <button onClick={handleClose}>close</button>
          </section>
        </div>
      );
    };
    

    工作代码 - https://codesandbox.io/s/adoring-moore-rsn97?file=/src/App.js:0-3665

    【讨论】:

    • 非常感谢!需要进行一些调整,但就是这样。稍后我会告诉你的。
    • 你好@Sarun UK。无论出于何种原因,如果我为同一项目选择一个句点,它会返回相同的结果。并且总共显示了最后一个时期的细节。这个想法是,它显示每个期间的项目详细信息,并且总体上显示整行或整列的详细信息,具体取决于选择哪一个。我们如何解决它?要解决的另一件事是对每个期间的总数执行相同的操作。
    猜你喜欢
    • 2015-11-25
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    相关资源
    最近更新 更多