Просмотр исходного кода

(refactor): 将 操作历史 功能从 dragact 中移出
(changed): 添加 dragact 的 props 中的 layout 改变时 重新计算 mapLayout 等的逻辑

chuancey 7 лет назад
Родитель
Сommit
368a5b4118
3 измененных файлов с 150 добавлено и 100 удалено
  1. 122 0
      src/HistoryLayout/HistoryLayout.tsx
  2. 12 8
      src/HistoryLayout/index.tsx
  3. 16 92
      src/lib/dragact.tsx

+ 122 - 0
src/HistoryLayout/HistoryLayout.tsx

@@ -0,0 +1,122 @@
+import * as React from 'react';
+
+import { DragactProps, DragactLayoutItem, Dragact } from '../lib/dragact';
+import { GridItemEvent } from '../lib/GridItem';
+
+interface HistoryDragactState {
+  layout: DragactLayoutItem[]
+}
+
+export class HistoryDragact extends React.Component<DragactProps, HistoryDragactState > {
+  _actionsHistory : string[] = []
+  _cacheLayouts: string;
+  _activeItem: GridItemEvent
+  _dragact: Dragact | null
+  constructor(props: DragactProps) {
+      super(props);
+      this.state= {layout: props.layout} as any;
+  }
+
+  _cacheCurrentLayoutStart = (layoutItem: GridItemEvent) => {
+      this._activeItem = layoutItem
+      if (!this._dragact) {
+          return;
+      }
+      this._cachingLayouts(this._dragact);
+  }
+
+  _cacheCurrentLayoutEnd = (layoutItem: GridItemEvent) => {
+      const { GridY, GridX, h, w } = this._activeItem;
+      if (GridX === layoutItem.GridX && GridY === layoutItem.GridY && h === layoutItem.h && w === layoutItem.w) {
+          return;
+  }
+      this._storeLayoutToHistory(this._cacheLayouts)
+  }
+ 
+  _cachingLayouts = (d: Dragact) => {
+      const initiateSnapShot = JSON.stringify({
+          layout: d.getLayout(),
+      })
+      return this._cacheLayouts = initiateSnapShot;
+  }
+
+  goBack = () => {
+      const mapLayoutHistory = this._actionsHistory;
+      if (mapLayoutHistory.length > 1) {
+          const last = mapLayoutHistory.pop();
+          if(!last) {
+              return;
+          }
+          this._changeDractLayouts(last);
+      }
+  }
+
+  reset = () => {
+      if (!this._dragact) {
+          return;
+      }
+      this._cachingLayouts(this._dragact);
+      this._storeLayoutToHistory(this._cacheLayouts);
+      const initiateSnapShot = this._actionsHistory[0];
+      this._changeDractLayouts(initiateSnapShot);        
+  }
+  
+  clear = () => {
+      const initiateSnapShot = this._actionsHistory[0];
+      this._actionsHistory = this._actionsHistory.slice(0, 1);
+      this._changeDractLayouts(initiateSnapShot);
+  }
+
+  onDragStart = (event: GridItemEvent) => {
+      this._cacheCurrentLayoutStart(event)
+      this.props.onDragStart && this.props.onDragStart(event)
+  }
+
+  onDragEnd = (event: GridItemEvent) => {
+      this._cacheCurrentLayoutEnd(event);
+      this.props.onDragEnd && this.props.onDragEnd(event)
+  }
+
+  _changeDractLayouts = (snapshot: string) => {
+      if(!this._dragact) {
+          return;
+      }
+      try {
+          const {layout} = JSON.parse(snapshot);
+          this.setState({
+              layout
+          })
+      }catch (e) {
+      }
+     
+  }
+
+  _storeLayoutToHistory = (layouts: string) => {
+      this._actionsHistory.push(layouts);
+  }
+
+  componentDidMount() {
+      if (this._dragact) {
+          const initiateSnapShot = this._cachingLayouts(this._dragact);
+          this._storeLayoutToHistory(initiateSnapShot)
+      }
+  }
+
+  componentWillReceiveProps(nextProps: DragactProps) {
+      this.setState({
+          layout: nextProps.layout
+      })
+  }
+  _dragactRefCallback = (d: Dragact) => {
+      this._dragact = d;
+  }
+
+  get getDragact() {
+      return this._dragact;
+  }
+
+  render () {
+      const layout = this.state.layout;
+      return <Dragact ref={this._dragactRefCallback} {...this.props} layout={layout} onDragStart={this.onDragStart} onDragEnd={this.onDragEnd} />
+      }
+}

+ 12 - 8
src/HistoryLayout/index.tsx

@@ -1,10 +1,9 @@
 import *as React from 'react';
-import { Dragact, DragactLayoutItem, GridItemProvided } from '../../src/lib/dragact'
+import { DragactLayoutItem, GridItemProvided} from '../../src/lib/dragact'
+import { HistoryDragact } from './HistoryLayout'
 import { Words } from './largedata';
 import './index.css';
 
-
-
 const fakeData = () => {
     var Y = 0;
     return Words.map((item, index) => {
@@ -48,7 +47,7 @@ export const Card: (any: any) => any = ({ item, provided }) => {
 
 
 export class HistoryDemo extends React.Component<{}, {}> {
-    drag: Dragact | null
+    drag: HistoryDragact | null
     render() {
         const margin: [number, number] = [5, 5];
         const dragactInit = {
@@ -72,15 +71,20 @@ export class HistoryDemo extends React.Component<{}, {}> {
                     </h1>
                     <button onClick={ () => {
                         if (this.drag) {
-                            this.drag.historyBack();
+                            this.drag.goBack();
                         }
                     }}>back</button>
                     <button onClick={ () => {
                         if (this.drag) {
-                            this.drag.resetLayout();
+                            this.drag.reset();
                         }
                     }}>reset</button>
-                    <Dragact
+                    <button onClick={ () => {
+                        if (this.drag) {
+                            this.drag.clear();
+                        }
+                    }}>clear</button>
+                    <HistoryDragact
                         {...dragactInit}
                         placeholder={true}
                         ref={n => this.drag = n}
@@ -95,7 +99,7 @@ export class HistoryDemo extends React.Component<{}, {}> {
                                 provided={provided}
                             />
                         }}
-                    </Dragact>
+                    </HistoryDragact>
                 </div>
             </div>
         )

+ 16 - 92
src/lib/dragact.tsx

@@ -118,10 +118,7 @@ export interface GridItemProvided {
 }
 
 export class Dragact extends React.Component<DragactProps, DragactState> {
-    mapLayoutHistory : string[] = []
-    cacheLayouts: string;
-    activeItem: GridItemEvent
-    
+   
     constructor(props: DragactProps) {
         super(props)
         this.onDrag = this.onDrag.bind(this)
@@ -142,78 +139,11 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
             mapLayout: undefined
         }
     }
-   
-    historyBack = () => {
-        const mapLayoutHistory = this.mapLayoutHistory;
-        if (mapLayoutHistory.length > 1) {
-            const last = mapLayoutHistory.pop();
-            if(!last) {
-                return;
-            }
-            try {
-                const {mapLayout, layout} = JSON.parse(last);
-                this.setState({
-                    mapLayout,
-                    layout
-                })
-            }catch (e) {
-            }
-            
-        }
-    }
-
-    resetLayout = () => {
-       
-        const { compacted, mapLayout } = this.recalculateLayout(this.props.layout)
-        this.cachingLayout();
-        this.storeLayoutToHistory();
-        this.setState({
-            layout: compacted,
-            mapLayout
-        })
-    }
-
-    get isHistoryMode () {
-        return !!this.props.history;
-    }
-
-    cacheCurrentLayoutStart = (layoutItem: GridItemEvent) => {
-        this.activeItem = layoutItem
-        this.cachingLayout();
-    }
-
-    cacheCurrentLayoutEnd = (layoutItem: GridItemEvent) => {
-        const { GridY, GridX, h, w } = this.activeItem;
-        if (GridX === layoutItem.GridX && GridY === layoutItem.GridY && h === layoutItem.h && w === layoutItem.w) {
-            return;
-        }
-        this.storeLayoutToHistory()
-    }
-
-    cachingLayout = () => {
-        if(!this.isHistoryMode) {
-            return;
-        }
-        const { mapLayout, layout } = this.state
-        this.cacheLayouts = JSON.stringify({
-            mapLayout,
-            layout
-        })
-    }
-
-    storeLayoutToHistory = () => {
-        if(!this.isHistoryMode) {
-            return;
-        }
-        this.mapLayoutHistory.push(this.cacheLayouts);
-    }
 
     onResizeStart = (layoutItem: GridItemEvent) => {
         const { GridX, GridY, w, h } = layoutItem
         if (this.state.mapLayout) {
-            this.cacheCurrentLayoutStart(layoutItem);
             const newlayout = syncLayout(this.state.mapLayout, layoutItem)
-            
             this.setState({
                 GridXMoving: GridX,
                 GridYMoving: GridY,
@@ -225,6 +155,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                 dragType: 'resize'
             })
         }
+        this.props.onDragStart && this.props.onDragStart(layoutItem);
     }
 
     onResizing = (layoutItem: GridItemEvent) => {
@@ -244,7 +175,6 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
 
     onResizeEnd = (layoutItem: GridItemEvent) => {
         const { compacted, mapLayout } = compactLayout(this.state.layout, undefined, this.state.mapLayout)
-        this.cacheCurrentLayoutEnd(layoutItem)
         this.setState({
             placeholderShow: false,
             layout: compacted,
@@ -257,7 +187,6 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
     onDragStart(bundles: GridItemEvent) {
         const { GridX, GridY, w, h } = bundles
         if (this.state.mapLayout) {
-            this.cacheCurrentLayoutStart(bundles);
             this.setState({
                 GridXMoving: GridX,
                 GridYMoving: GridY,
@@ -269,12 +198,10 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                 dragType: 'drag'
             })
         }
-
-        this.props.onDragStart && this.props.onDragStart(bundles)
+        this.props.onDragStart && this.props.onDragStart(bundles);
     }
 
     onDrag(layoutItem: GridItemEvent) {
-
         const { GridY, UniqueKey } = layoutItem;
         const moving = GridY - this.state.GridYMoving;
 
@@ -292,7 +219,6 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
 
     onDragEnd(layoutItem: GridItemEvent) {
         const { compacted, mapLayout } = compactLayout(this.state.layout, undefined, this.state.mapLayout)
-        this.cacheCurrentLayoutEnd(layoutItem)
         this.setState({
             placeholderShow: false,
             layout: compacted,
@@ -301,6 +227,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
         })
         this.props.onDragEnd && this.props.onDragEnd(layoutItem);
     }
+
     renderPlaceholder() {
         if (!this.state.placeholderShow) return null
         var { col, width, padding, rowHeight, margin, placeholder } = this.props
@@ -349,8 +276,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                     mapLayout
                 })
             }
-        }
-        if (this.props.layout.length < nextProps.layout.length) {//add
+        }  else  if (this.props.layout.length < nextProps.layout.length) {//add
             var item;
             for (const idx in nextProps.layout) {
                 const i = nextProps.layout[idx];
@@ -373,26 +299,24 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                     mapLayout
                 })
             }
+        } else {
+            this.recalculateLayout(nextProps.layout, nextProps.col);
         }
-
     }
 
-    recalculateLayout = (layout: DragactLayoutItem[]) => {
-        layout = correctLayout(layout, this.props.col)
-        return compactLayout(layout, undefined, this.state.mapLayout);
+    recalculateLayout = (layout: DragactLayoutItem[], col: number) => {
+        const corrected = correctLayout(layout, col)
+        const { compacted, mapLayout } = compactLayout(corrected, undefined, undefined);
+        this.setState({
+            layout: compacted,
+            mapLayout: mapLayout,
+            containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight, false)
+        })
     }
 
     componentDidMount() {
         setTimeout(() => {
-            const { compacted, mapLayout } = this.recalculateLayout(this.state.layout);
-            this.setState({
-                layout: compacted,
-                mapLayout: mapLayout,
-                containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1], this.state.containerHeight, false)
-            }, () => {
-                this.cachingLayout();
-                this.storeLayoutToHistory();
-            })
+            this.recalculateLayout(this.state.layout, this.props.col)
         }, 1);
     }