最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】AntD Pro中支持剧本剧本编写时拖动排序单个对话

拖动 crifan 1606浏览 0评论
现在用Antd Pro已经实现剧本编写的新建剧本中,新增多个对话:
以及插入儿歌之后的效果是:
但是希望可以:
手动拖动排序,以实现:
不小心中间漏了,想要在中间的位置插入某条对话
antd pro 拖拽
希望在antdpro中通过拖拽实现手动排序功能,不知antd是否已有解决方案或最佳实践? · Issue #1135 · ant-design/ant-design-pro
表格 Table – Ant Design
“拖拽排序
使用自定义元素,我们可以集成 react-dnd 来实现拖拽排序。”
社区精选组件 – Ant Design
react-dnd/react-dnd: Drag and Drop for React
-》
http://react-dnd.github.io/react-dnd/examples-chessboard-tutorial-app.html
mzabriskie/react-draggable: React draggable component
-》
好像都不是我们希望的效果
估计是要高度定制化了。
列表交换位置 ListSort – Ant Motion
抽空看看
树形控件 Tree – Ant Design
支持树状的拖动
-》或许可以集成到这里
React可拖动排序表格 – CSDN博客
-》
很接近我们需要的
antd-pro新增页面和功能详细步骤 – CSDN博客
后来也发现了:
antd pro中,table也支持拖动:
不过发现一些小缺点:
鼠标移动到某行,鼠标变成可拖动,但是对于每行的单元格直接可以编辑的话,是不是就没法直接编辑了?
以及每次新增一行,也要动态的调整新增一行的数据,不知道是否会有其他不方便的
参考人家集成了react-dnd的代码
先去把代码尝试合并进来,看看能不能实现拖动的效果
之后再去考虑,在拖动之前可以实时编辑内容
-》如果不行,就单独设置按钮,开始拖动调整顺序,然后内容只读,结束拖动调整顺序,再允许编辑单元格内容
同时参考:
React DnD
react-dnd/react-dnd: Drag and Drop for React
React DnD demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
➜  xxx git:(master) ✗ npm install --save react-dnd react-dnd-html5-backend
 
npm WARN @babel/plugin-proposal-export-default@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. You must install peer dependencies yourself.
npm WARN @babel/plugin-proposal-export-namespace@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. Youmust install peer dependencies yourself.
npm WARN @babel/plugin-syntax-dynamic-import@7.0.0-beta.51 requires a peer of @babel/core@>=7.0.0-beta.50 <7.0.0-rc.0 but none is installed. You must install peer dependencies yourself.
npm WARN @babel/plugin-syntax-export-extensions@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-react-app@2.1.0 requires a peer of babel-eslint@^7.2.3 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-react-app@2.1.0 requires a peer of eslint-plugin-jsx-a11y@^5.1.1 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-umi@0.1.4 requires a peer of eslint-plugin-jsx-a11y@^5.1.1 but none is installed. You must install peer dependencies yourself.
npm WARN react-fittext@1.0.0 requires a peer of react@^15.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN react-fittext@1.0.0 requires a peer of react-dom@^15.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN ts-jest-babel-7@22.0.7 requires a peer of jest@^22.0.1 || ^22.1.0-alpha.1 || ^23.0.0-alpha.1 but none is installed. You must install peer dependencies yourself.
 
+ react-dnd-html5-backend@5.0.1
+ react-dnd@5.0.0
added 7 packages from 2 contributors in 29.812s
再去试试代码
但是看到代码中还有个:immutability-helper
好像也需要去安装?
immutability-helper
kolodny/immutability-helper: mutate a copy of data without changing the original source
Immutability Helpers – React
不可变数据的辅助工具(Immutability Helpers) – React 中文版 – 极客学院Wiki
先试试:
1
import update from 'react-addons-update';
结果:
1
Module not found: Can't resolve 'react-addons-update' in
算了,去安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
npm install immutability-helper --save
 
➜  xxx git:(master) ✗ npm install immutability-helper --save
npm WARN @babel/plugin-proposal-export-default@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. You must install peer dependencies yourself.
npm WARN @babel/plugin-proposal-export-namespace@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. Youmust install peer dependencies yourself.
npm WARN @babel/plugin-syntax-dynamic-import@7.0.0-beta.51 requires a peer of @babel/core@>=7.0.0-beta.50 <7.0.0-rc.0 but none is installed. You must install peer dependencies yourself.
npm WARN @babel/plugin-syntax-export-extensions@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-react-app@2.1.0 requires a peer of babel-eslint@^7.2.3 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-react-app@2.1.0 requires a peer of eslint-plugin-jsx-a11y@^5.1.1 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-umi@0.1.4 requires a peer of eslint-plugin-jsx-a11y@^5.1.1 but none is installed. You must install peer dependencies yourself.
npm WARN react-fittext@1.0.0 requires a peer of react@^15.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN react-fittext@1.0.0 requires a peer of react-dom@^15.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN ts-jest-babel-7@22.0.7 requires a peer of jest@^22.0.1 || ^22.1.0-alpha.1 || ^23.0.0-alpha.1 but none is installed. You must install peer dependencies yourself.
 
+ immutability-helper@2.7.1
added 1 package from 1 contributor in 43.217s
 
➜  xxx git:(master) ✗ npm install --save react-addons-update
npm WARN @babel/plugin-proposal-export-default@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. You must install peer dependencies yourself.
npm WARN @babel/plugin-proposal-export-namespace@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. Youmust install peer dependencies yourself.
npm WARN @babel/plugin-syntax-dynamic-import@7.0.0-beta.51 requires a peer of @babel/core@>=7.0.0-beta.50 <7.0.0-rc.0 but none is installed. You must install peer dependencies yourself.
npm WARN @babel/plugin-syntax-export-extensions@7.0.0-beta.32 requires a peer of @babel/core@7.0.0-beta.32 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-react-app@2.1.0 requires a peer of babel-eslint@^7.2.3 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-react-app@2.1.0 requires a peer of eslint-plugin-jsx-a11y@^5.1.1 but none is installed. You must install peer dependencies yourself.
npm WARN eslint-config-umi@0.1.4 requires a peer of eslint-plugin-jsx-a11y@^5.1.1 but none is installed. You must install peer dependencies yourself.
npm WARN react-fittext@1.0.0 requires a peer of react@^15.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN react-fittext@1.0.0 requires a peer of react-dom@^15.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN ts-jest-babel-7@22.0.7 requires a peer of jest@^22.0.1 || ^22.1.0-alpha.1 || ^23.0.0-alpha.1 but none is installed. You must install peer dependencies yourself.
 
+ react-addons-update@15.6.2
added 1 package in 28.963s
然后再去试试
弄了半天,终于把demo的代码,跑起来了:
目前的合并的demo代码是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
import { Table } from 'antd';
import { DragDropContext, DragSource, DropTarget } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import update from 'immutability-helper';
 
const FormItem = Form.Item;
const InputGroup = Input.Group;
const { TextArea } = Input;
const { Option } = Select;
 
function dragDirection(
  dragIndex,
  hoverIndex,
  initialClientOffset,
  clientOffset,
  sourceClientOffset,
) {
  const hoverMiddleY = (initialClientOffset.y - sourceClientOffset.y) / 2;
  const hoverClientY = clientOffset.y - sourceClientOffset.y;
  if (dragIndex < hoverIndex && hoverClientY > hoverMiddleY) {
    return 'downward';
  }
  if (dragIndex > hoverIndex && hoverClientY < hoverMiddleY) {
    return 'upward';
  }
}
 
class BodyRow extends
React.Component
 {
  render() {
    const {
      isOver,
      connectDragSource,
      connectDropTarget,
      moveRow,
      dragRow,
      clientOffset,
      sourceClientOffset,
      initialClientOffset,
      ...restProps
    } = this.props;
    const style = { ...restProps.style, cursor: 'move' };
 
    let className = restProps.className;
    if (isOver && initialClientOffset) {
      const direction = dragDirection(
        dragRow.index,
        restProps.index,
        initialClientOffset,
        clientOffset,
        sourceClientOffset
      );
      if (direction === 'downward') {
        className += ' drop-over-downward';
      }
      if (direction === 'upward') {
        className += ' drop-over-upward';
      }
    }
 
    return connectDragSource(
      connectDropTarget(
        <tr
          {...restProps}
          className={className}
          style={style}
        />
      )
    );
  }
}
 
const rowSource = {
  beginDrag(props) {
    return {
      index: props.index,
    };
  },
};
 
const rowTarget = {
  drop(props, monitor) {
    const dragIndex = monitor.getItem().index;
    const hoverIndex = props.index;
 
    // Don't replace items with themselves
    if (dragIndex === hoverIndex) {
      return;
    }
 
    // Time to actually perform the action
    props.moveRow(dragIndex, hoverIndex);
 
    // Note: we're mutating the monitor item here!
    // Generally it's better to avoid mutations,
    // but it's good here for the sake of performance
    // to avoid expensive index searches.
    monitor.getItem().index = hoverIndex;
  },
};
 
const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
  connectDropTarget: connect.dropTarget(),
  isOver: monitor.isOver(),
  sourceClientOffset: monitor.getSourceClientOffset(),
}))(
  DragSource('row', rowSource, (connect, monitor) => ({
    connectDragSource: connect.dragSource(),
    dragRow: monitor.getItem(),
    clientOffset: monitor.getClientOffset(),
    initialClientOffset: monitor.getInitialClientOffset(),
  }))(BodyRow)
);
 
const columns = [
  // {
  //   title: 'Name',
  //   dataIndex: 'name',
  //   key: 'name',
  // }, {
  //   title: 'Age',
  //   dataIndex: 'age',
  //   key: 'age',
  // }, {
  //   title: 'Address',
  //   dataIndex: 'address',
  //   key: 'address',
  // },
  {
    title: '序号',
    // dataIndex: 'number',
    // rowKey: 'number',
    // fixed: 'left',
    render(text, record, index) {
      return index + 1;
    },
  },
  {
    title: 'Speaker/Song',
    dataIndex: 'speakerOrSong',
    key: 'speakerOrSong',
  },
  {
    title: 'Content/Address',
    dataIndex: 'contentOrAddress',
    key: 'contentOrAddress',
  },
];
 
/* eslint-disable */
 
class DragSortingTable extends
React.Component
 {
  state = {
    data: [
      // {
      //   key: '1',
      //   name: 'John Brown',
      //   age: 32,
      //   address: 'New York No. 1 Lake Park',
      // }, {
      //   key: '2',
      //   name: 'Jim Green',
      //   age: 42,
      //   address: 'London No. 1 Lake Park',
      // }, {
      //   key: '3',
      //   name: 'Joe Black',
      //   age: 32,
      //   address: 'Sidney No. 1 Lake Park',
      // }
      {
        key: '1',
        speakerOrSong: 'A',
        contentOrAddress: 'hi boy',
      },
      {
        key: '2',
        speakerOrSong: 'B',
        contentOrAddress: 'hello',
      },
      {
        key: '3',
        speakerOrSong: 'A',
        contentOrAddress: 'what are you doing?',
      },
      {
        key: '4',
        speakerOrSong: 'B',
        contentOrAddress: 'I am singing',
      },
      {
        key: '5',
        speakerOrSong: 'Song',
        contentOrAddress: 'this is a apple.mp3',
      },
    ],
  }
 
  components = {
    body: {
      row: DragableBodyRow,
    },
  }
 
  moveRow = (dragIndex, hoverIndex) => {
    const { data } = this.state;
    const dragRow = data[dragIndex];
 
    this.setState(
      update(this.state, {
        data: {
          $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
        },
      }),
    );
  }
 
  render() {
    return (
      <Table
        columns={columns}
        dataSource={this.state.data}
        components={
this.components
}
        onRow={(record, index) => ({
          index,
          moveRow: this.moveRow,
        })}
      />
    );
  }
}
/* eslint-disable */
 
const DemoSortableTable = DragDropContext(HTML5Backend)(DragSortingTable);
 
 
  render() {
    ...
 
    return (
      <PageHeaderLayout
        title="新建剧本"
      >
        ...
            </FormItem>
 
            {/* {this.buildDialog()} */}
 
            {/* <div style={{ width:800, height: 360 }}> */}
              {/* { this.DemoSortableTable } */}
              <DemoSortableTable />
            {/* </div> */}
 
            <FormItem {...submitFormLayout} style={{ marginTop: 32 }}>
              ...
    );
  }
}
然后再去想办法,合并到现有的页面中去
以及合并自己的业务逻辑
期间涉及到:
【已解决】Reactjs中如何在Component的外部改变和获取state状态值
然后算是完成了:外部列表变化,可以传递到内部的可拖动排序的列表了
但是还要去解决:
【已解决】reactjs中如何获取子元素中当前的状态值
另外,再去解决此处需要实时编辑可拖动的表格中的单元格的值:
【已解决】Antd Pro的ReactJS中实现既可以编辑单元格值又可以拖动排序的表格
此时已经实现想要的拖动排序的效果了。
且至此在可拖动和可编辑之前切换。
接着去优化一下整个代码结构
【已解决】剧本编写系统中优化可拖动排序可编辑单元格的表格
如此,即可完成,根据传入模式决定当前显示的模式:
可编辑模式:支持点击单元格,直接编辑cell的值
还是
可拖动:通过拖动行到别的位置,实现更换row行到顺序。
具体代码和效果,详见:
【已解决】剧本编写系统中优化可拖动排序可编辑单元格的表格

转载请注明:在路上 » 【已解决】AntD Pro中支持剧本剧本编写时拖动排序单个对话

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
80 queries in 0.371 seconds, using 22.29MB memory