2016-02-28 5 views
7

Gibt es eine Möglichkeit, das Layout eines Artikels programmgesteuert zu ändern w und h? Der Anwendungsfall ist ein "Zusammenfalten" -Knopf, der die Höhe auf eine konstante Höhe reduziert, genug, um den Kopf des Gegenstands zu verlassen. Um dies zu tun, war meine ursprüngliche Idee, layouts in dem Zustand der Komponente zu behalten und die Höhe des kollabierten Elements/s auf eine andere konstante Höhe manuell zu ändern.Programmatische Änderung der Höhe/Breite von Objekten im react-grid-Layout

Es sieht jedoch so aus, als würde die Bibliothek nach dem ersten Rendering die Änderungen an layout ignorieren. Ist das der Fall oder ist es ein Fehler an meinem Ende? Und wenn es normales Verhalten ist, gibt es einen anderen Weg, die Höhe programmatisch zu ändern?

Hier ist eine eigenständige Komponente, die react-grid-layout implementiert. Es sind zwei "Widgets", die einen onClick-Handler haben, um sie "zu reduzieren". Wenn Sie den Status festlegen, werden die Layouts neu gerendert und die Layouts neu berechnet, so dass alle reduzierten Elemente eine reduzierte Höhe aufweisen. Die Konsolenprotokoll-Statements zeigen, dass die gerenderten Komponenten das korrekte neue Layout haben, aber es wird nicht auf dem Bildschirm wiedergegeben, was mich zu der Annahme verleitet, dass es einen weiteren Bezug auf die Höhe gibt.

jsFiddle example

import React, { Component } from 'react'; 

import GridLayout, { WidthProvider } from 'react-grid-layout'; 
const Grid = WidthProvider(GridLayout); 

// # WidgetsContainer 
// Container WidgetsContainer component. 
class WidgetsContainer extends Component { 

    static defaultProps = { 
     isDraggable: true, 
     isResizable: true, 
     rowHeight: 1, 
     cols: 12, 
    } 

    constructor(props) { 
     super(props); 
     this.state = { 
      layouts: [ 
       { 
        i: 'item_1', 
        x: 0, 
        y: 0, 
        w: 5, 
        h: 25, 
       }, { 
        i: 'item_2', 
        x: 5, 
        y: 0, 
        w: 7, 
        h: 30, 
       }, 
      ], 
      collapsedWidgets: {}, 
     }; 
    } 

    toggleWidget(id) { 
     return() => { 
      const newState = {...this.state.collapsedWidgets}; 
      const collapsed = typeof newState[id] === 'boolean' ? newState[id] : false; 

      newState[id] = !collapsed; 
      this.setState({ 
       collapsedWidgets: newState, 
      }); 
     } 

    } 

    onResize(layouts) { 
     this.setState({ 
      layouts, 
     }); 
    } 

    getModifiedLayouts() { 
     const { layouts, collapsedWidgets } = this.state; 

     const newLayouts = layouts.map(layout => { 
      const newLayout = { ...layout }; 
      if (collapsedWidgets[newLayout.i]) { 
       newLayout.h = 5; 
      } 
      return newLayout; 
     }); 

     return newLayouts; 
    } 

    getWidgets() { 
     const widgets = [{ 
      component: <div style={{ height: '250px', background: 'lightgray' }}>Content</div>, 
      title: 'Item 1', 
      id: 'item_1', 
     }, { 
      component: <div style={{ height: '310px', background: 'lightgray' }}>Content 2</div>, 
      title: 'Item 2', 
      id: 'item_2', 
     }]; 
     return widgets; 
    } 

    generateDOM() { 
     const widgets = this.getWidgets(); 

     const modifiedLayouts = this.getModifiedLayouts(); 

     return widgets.map((widget, i) => { 
      return (<div key={i} _grid={modifiedLayouts[i]}> 
       <div style={{ background: 'gray' }} onClick={::this.toggleWidget(widget.id)}> 
        {widget.title} 
        {widget.component} 
       </div> 
      </div>); 
     }); 
    } 

    render() { 
     const widgets = this.generateDOM(); 
     console.log(widgets[0].props._grid) 
     return (<div style={{ marginTop: '15px' }}> 
       {widgets ? <Grid className="layout" 
        {...this.props} 
        onResizeStop={::this.onResize} 
       > 
        {widgets} 
       </Grid> : null} 
      </div>); 
    } 
} 

export default WidgetsContainer; 

Antwort

3

Es stellt sich heraus, der Trick ist, nicht die _grid zu verwenden und stattdessen die layout Stütze auf der Grid Komponente verwenden. Hier ist ein funktionierendes jsfiddle:

http://jsfiddle.net/zekedroid/d9o75d24/

Und der Code:

const Grid = ReactGridLayout.WidthProvider(ReactGridLayout); 

class Logo extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      layouts: [ 
       { 
        i: '0', 
        x: 0, 
        y: 0, 
        w: 5, 
        h: 25, 
       }, { 
        i: '1', 
        x: 5, 
        y: 0, 
        w: 7, 
        h: 30, 
       }, 
      ], 
      collapsedWidgets: {}, 
     }; 
    } 

    toggleWidget(id) { 
     return() => { 
      const newState = {...this.state.collapsedWidgets}; 
      const collapsed = typeof newState[id] === 'boolean' ? newState[id] : false; 

      newState[id] = !collapsed; 
      this.setState({ 
       collapsedWidgets: newState, 
      }); 
     } 

    } 

    onResize(layouts) { 
     this.setState({ 
      layouts, 
     }); 
    } 

    getModifiedLayouts() { 
     const { layouts, collapsedWidgets } = this.state; 

     const newLayouts = layouts.map(layout => { 
      const newLayout = { ...layout }; 
      if (collapsedWidgets[newLayout.i]) { 
       newLayout.h = 5; 
      } 
      return newLayout; 
     }); 

     return newLayouts; 
    } 

    getWidgets() { 
     const widgets = [{ 
      component: <div style={{ height: '250px', background: 'lightgray' }}>Content</div>, 
      title: 'Item 1', 
      id: '0', 
     }, { 
      component: <div style={{ height: '310px', background: 'lightgray' }}>Content 2</div>, 
      title: 'Item 2', 
      id: '1', 
     }]; 
     return widgets; 
    } 

    generateDOM() { 
     const widgets = this.getWidgets(); 

     return widgets.map((widget, i) => { 
      return (<div key={i} style={{ overflowY: 'auto' }}> 
       <div style={{ background: 'gray' }} onClick={this.toggleWidget(widget.id).bind(this)}> 
        {widget.title} 
        {widget.component} 
       </div> 
      </div>); 
     }); 
    } 

    render() { 
     const widgets = this.generateDOM(); 

     const modifiedLayouts = this.getModifiedLayouts(); 

     return (<div style={{ marginTop: '15px' }}> 
       {widgets ? <Grid className="layout" 
        {...this.props} 
        onResizeStop={this.onResize.bind(this)} 
        layout={modifiedLayouts} 
       > 
        {widgets} 
       </Grid> : null} 
      </div>); 
    } 
} 

Logo.defaultProps = { 
     isDraggable: true, 
     isResizable: true, 
     rowHeight: 1, 
     cols: 12, 
    } 



React.render(<Logo /> , document.getElementById('container')); 
Verwandte Themen