2016-02-28 9 views
7

Czy istnieje sposób programowej zmiany w i h układu elementu? Przypadkiem użycia jest przycisk "zwijania", który zmniejsza wysokość do stałej wysokości, wystarczającej do opuszczenia nagłówka przedmiotu. W tym celu moim pierwotnym pomysłem było utrzymanie layouts w stanie komponentu i ręczna zmiana wysokości zwiniętych elementów na inną stałą wysokość.Programowa zmiana wysokości/szerokości elementów w układzie siatki reakcji

Wygląda jednak na to, że po początkowym renderowaniu biblioteka zignoruje zmiany do layout. Czy to przypadek, czy jest to błąd na moim końcu? A jeśli jest to normalne zachowanie, czy istnieje inny sposób programowej zmiany wysokości?

Oto samodzielny komponent, który implementuje react-grid-layout. To dwa "widżety", które mają handler onClick, aby je "zwinąć". Po ustawieniu stanu powoduje on ponowne renderowanie i ponowne obliczanie układów, aby wszystkie zwinięte elementy miały zmniejszoną wysokość. Dane dziennika konsoli pokazują, że renderowane komponenty mają poprawny nowy układ, ale nie są odbijane na ekranie, co prowadzi do przekonania, że ​​istnieje inne odniesienie do wysokości.

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; 

Odpowiedz

3

Okazuje się Sztuką jest, aby nie używać _grid i zamiast używać layout rekwizyt na komponencie Grid. Oto jsfiddle pracy:

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

I kod:

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')); 
Powiązane problemy