2015-02-24 33 views
15

Sto scoprendo ReactJS e material-ui (http://material-ui.com/).UI materiale - Apri LeftNav/Drawer su AppBar fai clic su

Provo a creare un modello predefinito per la mia applicazione. Desidero utilizzare un AppBar e un LeftNav (rinominato in Drawer nelle nuove versioni) in componenti separati.

L'AppBar ha un pulsante di menu su di esso per impostazione predefinita. Voglio usarlo per aprire il LeftNav ma non so come posso chiamare la mia funzione componente LeftBarComponent per aprirlo.

Ho quasi capito come comunicare tra componenti, ma nel mio caso, non so come potrei fare perché non c'è documentazione a riguardo. L'unica cosa che so per aprire l'elemento LeftNav è quello di utilizzare LeftNav.toggle()

http://material-ui.com/#/components/left-nav

Grazie per il vostro aiuto.

Default.jsx

use strict'; 

var React = require('react'); 
var pageStore = require('../../stores/page'); 

var MainNavbar = require('../modules/navbar.jsx'); 
var LeftNavbar = require('../modules/leftbar.jsx'); 

var getState = function() { 
    return { 
    title: pageStore.get().title 
    }; 
}; 

var DefaultComponent = React.createClass({ 
    mixins: [pageStore.mixin], 
    componentDidMount: function() { 
    pageStore.emitChange(); 
    }, 
    getInitialState: function() { 
    return getState(); 
    }, 
    render: function() { 
    return (
     /* jshint ignore:start */ 
     <div className="main-container"> 
     <MainNavbar /> 
     <LeftNavbar /> 
     <div className="content"> 
      {this.props.children} 
     </div> 
     </div> 
     /* jshint ignore:end */ 
    ); 
    }, 
    // Event handler for 'change' events coming from store mixins. 
    _onChange: function() { 
    this.setState(getState()); 
    } 
}); 

module.exports = DefaultComponent; 

navbar.jsx

'use strict'; 

var React = require('react'); 
var routeActions = require('../../actions/routes'); 

var MUI = require('material-ui'); 
var AppBar = MUI.AppBar; 

// Navbar Component 
// Application main menu 
// Usage: <Navbar /> 
var NavbarComponent = React.createClass({ 
    render: function() { 
    return (
     /* jshint ignore:start */ 
     <AppBar title="MyApp" onMenuIconButtonTouchTap={ this._handleClick }> 
     <div className="clear"></div> 
     </AppBar> 
     /* jshint ignore:end */ 
    ); 
    }, 
    _handleClick: function() 
    { 
    console.log('ok'); 
    } 
}); 

module.exports = NavbarComponent; 

leftbar.jsx

'use strict'; 

var React = require('react'); 
var routeActions = require('../../actions/routes'); 

var MUI = require('material-ui'); 
var LeftNav = MUI.LeftNav; 
var MenuItem = MUI.MenuItem; 

var menuItems = [ 
    { route: 'home', text: 'Home' }, 
    { route: 'about', text: 'About' }, 
]; 

// LeftBar Component 
// Application left menu 
// Usage: <LeftBar /> 
var LeftBarComponent = React.createClass({ 
    render: function() { 
    return (
     /* jshint ignore:start */ 
     <LeftNav menuItems={menuItems} docked={false} /> 
     /* jshint ignore:end */ 
    ); 
    }, 
    _handleClick: function() 
    { 
    console.log('ok'); 
    } 
}); 

module.exports = LeftBarComponent; 

risposta

5

In questo caso nee d per passare l'evento verso l'alto attraverso i componenti, quindi di nuovo verso il basso.

<MainNavbar onClickMenu=this.onClickMenu/> 
    <LeftNavbar isOpen=this.state.leftNavIsOpen/> 

Tuttavia, utilizzando questo in collaborazione con Reactjs non è ottimale, in quanto il componente materiale LeftNav non reagisce agli attributi, ma per chiamate di metodo come dicevi.

Per risolvere il problema, è possibile inserire un controllo nel metodo di rendering LeftNav, che controlla lo stato corrente e chiama() se necessario. In linea di principio ciò va contro il modo di pensare di React, in quanto uno stato è contenuto all'interno del componente figlio specifico e non nel DefaultComponent che lo gestisce.

render:function(){ 
    if(this.props.isOpen){ 
    LeftNav.open(); 
    } 
    return ... 
+0

Si veda anche la risposta per questa domanda: http://stackoverflow.com/questions/22639534/pass-props-to-parent-component-in-react-js –

5

Per chiarire cosa steinso Detto questo, è necessario inviare l'evento ad un'azione utilizzando l'architettura di flusso e quindi modificare in un negozio. Quindi invia un evento di modifica dell'emissione con EventEmitter. Questo farà partire un rendering sui componenti effettivi con lo stato aggiornato.

https://facebook.github.io/flux/

Se è necessario disporre di loro separati, allora, che sarebbe il modo migliore. Tuttavia, se puoi averli nello stesso componente, ad esempio "Principale", puoi semplicemente utilizzare un attributo ref e fare riferimento al componente.

module.exports = React.createClass({ 

    childContextTypes: { 
    muiTheme: React.PropTypes.object 
    }, 

    getChildContext: function() { 
    return { 
     muiTheme: ThemeManager.getCurrentTheme() 
    }; 
    }, 

    _toggleNav: function(){ 
    this.refs.leftNav.toggle(); 
    }, 

    render: function() { 
    return (
     <div> 
     <mui.LeftNav 
      ref='leftNav' 
      menuItems={menuItems} 
      docked={false} /> 
     <mui.AppBar 
      title='Default' 
      onLeftIconButtonTouchTap={this._toggleNav} /> 
     </div> 
    ); 
    } 

}); 

Mi piace così.

1

Sto usando Reagire con Material-UI e ho fatto questo utilizzando onLeftIconButtonTouchTap = {} this.handleToggle evento in AppBar.Per maggiori dettagli, è possibile consultare la documentazione ufficiale http://www.material-ui.com/#/components/app-bar

App.js

import React from 'react'; 
import AppBar from 'material-ui/AppBar'; 
import Drawer from 'material-ui/Drawer'; 
import MenuItem from 'material-ui/MenuItem'; 
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; 
import Dashboard from './Dashboard/dashboard.js'; 
import Information from './Information/information.js'; 
import './App.css'; 

class App extends React.Component { 

    constructor(props) { 
    super(props); 
    this.state = {open: false}; 
    } 

    handleToggle = (event) => this.setState({open: !this.state.open}); 

    render() { 

    const {styleFromProps} = this.props; 
    const contentStyle = { ...styleFromProps, transition: 'margin-left 450ms cubic-bezier(0.23, 1, 0.32, 1)' }; 

    if (this.state.open) { 
     contentStyle.marginLeft = 256; 
    } 

    return (
     <Router> 
      <div> 
      <AppBar title="AppTitle" onLeftIconButtonTouchTap={this.handleToggle} /> 

      <Drawer containerStyle={{height: 'calc(100% - 64px)', top: 64}} docked={true} width={200} open={this.state.open} zDepth={2}> 
       <Link to="/dashboard" style={{ textDecoration: 'none' }}><MenuItem>Dashboard</MenuItem></Link> 
       <Link to="/information" style={{ textDecoration: 'none' }}><MenuItem>Information</MenuItem></Link> 
      </Drawer> 

      <Route path="/dashboard" component={(props) => <Dashboard {...props} open={this.state.open}/>} /> 
      <Route path="/information" component={(props) => <Information {...props} open={this.state.open}/>} /> 
      </div> 
     </Router> 
    ); 
    } 
} 

export default App; 

penso che vi aiuterà.

+0

Grazie @Rohit Mi ha aiutato. Questo è quello che sto cercando. –

Problemi correlati