1

我想要一个网格,它总是有例如 3 行和 3 列。现在假设这些是我的网格项目

      <div className="myClass" key="1">1</div>
      <div className="myClass" key="2">2</div>
      <div className="myClass" key="3">3</div>
      <div className="myClass" key="4">4</div>
      <div className="myClass" key="5">5</div>
      <div className="myClass" key="6">6</div>
      <div className="myClass" key="7">7</div>
      <div className="myClass" key="8">8</div>
      <div className="myClass" key="9">9</div>

假设所有项目都具有相同的宽度和高度并且不可调整大小。

如果我将 9 拖到 6 也就是垂直方向,这些项目只会交换它们的位置。但是,如果我将 9 水平拖到 8 上,则 8 项将向下移动到新行,并且 9 将代替 8,而之前的 9 位置将为空。是否可以让项目在水平拖动期间也只是交换位置,而不是创建一个新行?

4

2 回答 2

0

所以我添加onLayoutChangeReactGridLayout

阅读代码注释以获取更多详细信息。

private onLayoutChange = (layout: any) => {
    const fixedLayout = this.fixLayout(layout)
    this.setState({
      layout: fixedLayout
    })
  }

  /**
   * The `react-grid-layout` lib is not swapping items during horizontal dragover
   * Rather it moves the items into a new row
   * Since we need a static 3x3 row, let's fix that
   */
  private fixLayout = (layout: any) => {
    // `y` is calculated by `h` in the layout object, since `h` is 20
    // first row will be 0, second 20, third 40
    const maxY = 40

    // when an item goes to a new row, there is an empty column in the maxY row
    // so here we find which columns exist
    // tslint:disable-next-line:max-line-length
    const maxRowXs = layout.map((item: any) => item.y === maxY ? item.x : null).filter((value: any) => value !== null)

    // xs or cols, we only have 3 cols
    const xs = [0,1,2]

    // find the missing col
    // tslint:disable-next-line:max-line-length
    const missingX = xs.find((value: any) => maxRowXs.every((maxRowX: number) => maxRowX !== value))

    // bring the item from the new row into maxY row
    // and place it in the missing column
    const fixedLayout = layout.map((item: any) => {
      if (item.y > maxY) {
        return {
          ...item,
          y: maxY,
          x: missingX
        }
      }
      return item
    })
    return fixedLayout
  }
于 2018-08-24T09:30:30.587 回答
0

Hayk Safaryan 的答案很棒并修复了这个确切的问题,但是我发现添加“maxRows = {3}”修复了答案中的一个错误,您可以在其中堆叠 4,因为 ui 在布局数据之前更新。

我的代码:

import { useState } from "react";
import GridLayout from "react-grid-layout";

const Drag = () => {
  // layout is an array of objects, see the demo for more complete usage
  const [layout,setLayout] = useState([
    { i: "a", x: 0, y: 0, w: 1, h: 1, isResizable: false, },
    { i: "b", x: 1, y: 0, w: 1, h: 1, isResizable: false, },
    { i: "c", x: 2, y: 0, w: 1, h: 1, isResizable: false, },
    { i: "d", x: 0, y: 1, w: 1, h: 1, isResizable: false, },
    { i: "e", x: 1, y: 1, w: 1, h: 1, isResizable: false, },
    { i: "f", x: 2, y: 1, w: 1, h: 1, isResizable: false, },
    { i: "g", x: 0, y: 2, w: 1, h: 1, isResizable: false, },
    { i: "h", x: 1, y: 2, w: 1, h: 1, isResizable: false, },
    { i: "i", x: 2, y: 2, w: 1, h: 1, isResizable: false, },
  ]);

  
  return (
    <GridLayout
      className="layout"
      layout={layout}
      cols={3}
      rowHeight={100}
      width={1500}
      onLayoutChange={e=>setLayout(fixLayout(e))}
      maxRows={3}
    >
      <div key="a" style={{ background: "grey" }}>
        a
      </div>
      <div key="b" style={{ background: "grey" }}>
        b
      </div>
      <div key="c" style={{ background: "grey" }}>
        c
      </div>
      <div key="d" style={{ background: "grey" }}>
        d
      </div>
      <div key="e" style={{ background: "grey" }}>
        e
      </div>
      <div key="f" style={{ background: "grey" }}>
        f
      </div>
      <div key="g" style={{ background: "grey" }}>
        g
      </div>
      <div key="h" style={{ background: "grey" }}>
        h
      </div>
      <div key="i" style={{ background: "grey" }}>
        i
      </div>
    </GridLayout>
  );
};

export default Drag;


/**
 * The `react-grid-layout` lib is not swapping items during horizontal dragover
 * Rather it moves the items into a new row
 * Since we need a static 3x3 row, let's fix that
 */
const fixLayout = (layout) => {
  // `y` is calculated by `h` in the layout object, since `h` is 20
  // first row will be 0, second 20, third 40
  const maxY = 2

  // when an item goes to a new row, there is an empty column in the maxY row
  // so here we find which columns exist
  // tslint:disable-next-line:max-line-length
  const maxRowXs = layout.map((item) => item.y === maxY ? item.x : null).filter((value) => value !== null)

  // xs or cols, we only have 3 cols
  const xs = [0,1,2]

  // find the missing col
  // tslint:disable-next-line:max-line-length
  const missingX = xs.find((value) => maxRowXs.every((maxRowX) => maxRowX !== value))

  // bring the item from the new row into maxY row
  // and place it in the missing column
  const fixedLayout = layout.map((item) => {
    if (item.y > maxY) {
      const fixedItem = {
        ...item,
        y: maxY,
        x: missingX
      }
      return fixedItem
    }
    return item
  })
  return fixedLayout
}
于 2021-08-09T11:23:02.427 回答