如何使用react-grid-layout创建动态拖放布局 [英] How to create dynamic drag and drop layout with react-grid-layout

查看:379
本文介绍了如何使用react-grid-layout创建动态拖放布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用

对于 Info 应该有两个应用程序,因此在一个网格中一个应用程序,而在另一个网格中另一个应用程序.

问题出在 generateDOM 中,因为该功能可以完美地生成布局,但是在一个布局中它对其他人重复所有相同的操作,如果长度为3,则它正在创建3个布局,即完全可以,但是在一种布局中是agian循环并显示重复数据

在此附上一张图片,该图片应如何显示在UI

解决方案

我认为问题是未使用布局,我还注意到lodash中对random的错误使用(但这不是必须的)

在映射 layout 时,我使用 data1.EmpData [l.i] 获取要显示的数据.

我还创建了一个

  const generateDOM =(lo)=>{//从布局生成具有属性的项目,而不是直接传递布局const layout = generateLayout();return _.map(layout,function(l){返回 (< div key = {l.i} data-grid = {l} className ="bg-success"< div> {lo [l.i] .empName}</div>{console.log(lo,l,active_menu)}</div>);});}; 

当我们渲染时,我们不需要地图,而只需一个调用:

 返回(<>{data1.map((d,ind)=>(< div className = {ind === active_menu吗?"compNameActive";:" compName"}>< p onClick = {()=>compClick(ind)}> {d.company_name}</p></div>))}< ReactGridLayout onLayoutChange = {onLayoutChange} {... props}>{generateDOM(data1 [active_menu] .comp_data)}</ReactGridLayout></>); 

sanbox2

I am using react-grid-layout to make drag-drop and resize components, So i am able to achieve the functionality as mentioned in the doc.

My Issue

  • I am creating dynamic UI so I am rendering my UI with data.
  • Here in this library I need to create layout like { {i: 'a', x: 0, y: 0, w: 1, h: 2}
  • When I am creating static UI I am able to achieve what I want.Here is working code sandbox

In static Ui with predefined layout I did like below.

    const layout = [
    { i: "a", x: 0, y: 0, w: 2, h: 1 },
    { i: "b", x: 2, y: 0, w: 2, h: 1 },
    { i: "c", x: 4, y: 0, w: 2, h: 1 },
    { i: "d", x: 6, y: 0, w: 2, h: 1 },
    { i: "e", x: 0, y: 2, w: 2, h: 1 }
  ];

<div className="App">
  <GridLayout
    className="layout"
    layout={layout}
    style={{ backgroundColor: "blue" }}
  >
    {layout.map((li) => (
      <div key={li.i} style={{ backgroundColor: "yellow" }}>
        {li.i}
      </div>
    ))}
  </GridLayout>

This is working fine, But here the layout I have defined is static, So for this I searched and got one example with dynamic height and width, which is creating a dynamic layout.

But that is creating the layout with just random numbers which is not showing up with my UI (as per my use), This is what I found out in library for dynamic UI

What I am trying to do

I have this data as in my state

const [data1, setData] = useState({
    EmpData: [
        {
            empId: 11,
            lay1: { i: 'a' },
            data: [
                {
                    firstName: 'Steve',
                    lastName: 'Smith',
                },
                {
                    firstName: 'Michel',
                    lastName: 'Muner',
                },
            ],
        },
        {
            empId: 12,
            lay1: { i: 'b' },
            data: [
                {
                    firstName: 'Charles',
                    lastName: 'Johnsen',
                },
                {
                    firstName: 'Glen',
                    lastName: 'Tyson',
                },
            ],
        },
        {
            empId: 13,
            lay1: { i: 'c' },
            data: [
                {
                    firstName: 'Steve',
                    lastName: 'Smith',
                },
                {
                    firstName: 'Michel',
                    lastName: 'Muner',
                },
            ],
        },
        {
            empId: 14,
            lay1: { i: 'd' },
            data: [
                {
                    firstName: 'Steve',
                    lastName: 'Smith',
                },
                {
                    firstName: 'Michel',
                    lastName: 'Muner',
                },
            ],
        },
        {
            empId: 15,
            lay1: { i: 'e' },
            data: [
                {
                    firstName: 'Steve',
                    lastName: 'Smith',
                },
                {
                    firstName: 'Michel',
                    lastName: 'Muner',
                },
            ],
        },
    ],
});

By above data I am creating Ui as per my need

return data1.EmpData.map((li, index) => (
        <div key={index.toString()} data-grid={index}"> </div> //what should I pass here as key and layout that I am not getting
            <>
                {li.data.map((l) => (
                    <>
                        <div>{l.firstName}</div>
                        <div>{l.lastName}</div>
                    </>
                ))}
            </>
        </div>
    ));
};

Passing key and creating dynamic layout is where I am not able to figure out how can I achieve this, as this is totally new thing to me.

My UI is totally dynamic Every time I am going to get dynamic data so that much cards or divs I need to show.

Here is my code sand box what I am trying to do dynamically

Edit / Update

The answer I got from @Daniil Loban is very helpfull, but when I am trying to loop with my real time data it is looping twice, That is hapenning because my data is little bit different of what I have shown here

Actually I am not able to understand I use data1.EmpData[l.i] to get data to display when I map layout. this line.

My data

    [
{
  compId: 5,
  company_name: "Info",
  comp_data: [
    {
      empId: 1,
      empName:"steve"
    },
    {
      empId: 2,
      empName:"meg"
    }
  ]
},
{
  compId: 6,
  company_name: "wipro",
  comp_data: [
    {
      empId: 11,
      empName:"mark"
    },
    {
      empId: 12,
      empName:"Tnml"
    }
  ]
}

]

  • How data goes is like company->employ of that company->data of that company,
  • So here company can be multiple employ can be multiple similarly for data
  • What i have updated in previous data I have not mentioned the company as I thought of writing minimal code.
  • I have added full code Now and Here is my code sandbox

The issue

  • Issue is it is repeating the data, I am getting duplicate data on display

  • I ll explain here like company namme->companydata->employe name this should be the perfect but what is happening is -- companyname->the in one div both employ I a, getting and in other again I am getting both ones

It should be for Info there are two employ so in one grid one employ and in other one the other employ.

The issue is in generateDOM this function as layout is generated perfectly but in one Layout it is repeating all then same for others, if lenght is 3 then it is creating 3 layouts which is totally fine, but inside one layout it is agian looping and showing duplicate data

Here by I am attaching one image how it should show on UI

解决方案

I think the problem was that layout was not used, I also noticed the incorrect use of random from lodash (but this is not essential)

I use data1.EmpData[l.i] to get data to display when I map layout.

I also created a sandbox where there is a button for dynamic addition, I think this is what you wanted.

  const generateDOM = () => {
    // Generate items with properties from the layout, rather than pass the layout directly
    const layout = generateLayout();
    return _.map(layout, function (l) {
      return (
        <div key={l.i} data-grid={l} className="bg-success">
          <>
            <div className="rounded" key="?"></div>
            {data1.EmpData[l.i].data.map((l) => (
              <>
                <div>{l.firstName}</div>
                <div>{l.lastName}</div>
              </>
            ))}
          </>
        </div>
      );
    });
  };

For updated question:

  const generateDOM = (lo) => {
    // Generate items with properties from the layout, rather than pass the layout directly
    const layout = generateLayout();
    return _.map(layout, function (l) {
      return (
        <div key={l.i} data-grid={l} className="bg-success">
          <div>{lo[l.i].empName}</div>
          {console.log(lo, l, active_menu)}
        </div>
      );
    });
  };

And when we render, we don't need map, but just one call:

  return (
    <>
      {data1.map((d, ind) => (
        <div className={ind === active_menu ? "compNameActive" : "compName"}>
          <p onClick={() => compClick(ind)}>{d.company_name}</p>
        </div>
      ))}
      <ReactGridLayout onLayoutChange={onLayoutChange} {...props}>
        {generateDOM(data1[active_menu].comp_data)}
      </ReactGridLayout>
    </>
  );

sanbox2

这篇关于如何使用react-grid-layout创建动态拖放布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆