2015-02-24 6 views
15

Я открываю ReactJS и материал-ui (http://material-ui.com/).Материал UI - Открыть LeftNav/Drawer на AppBar щелчок

Я пытаюсь создать шаблон по умолчанию для своего приложения. Я хочу использовать AppBar и LeftNav (переименованный в ящике в новых версиях) в разделенных компонентах.

У AppBar есть кнопка меню по умолчанию. Я хочу использовать его, чтобы открыть LeftNav, но я не знаю, как я могу вызвать функцию компонента LeftBarComponent, чтобы открыть его.

Я почти понял, как общаться между компонентами, но в моем случае я не знаю, как я мог это сделать, потому что нет документации об этом. Единственное, что я знаю, чтобы открыть элемент LeftNav является использование LeftNav.toggle()

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

Спасибо за вашу помощь.

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; 

ответ

5

В этом случае вам нужно передать событие вверх через ваши компоненты, а затем снова вниз.

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

Однако, используя это в сочетании с Reactjs не является оптимальным, так как компонент LeftNav материал не реагирует на атрибуты, но вызовы методов, как вы говорили.

Чтобы обойти, вы можете поместить проверку в метод визуализации LeftNav, который проверяет текущее состояние, и вызывает toggle(), если это необходимо. В принципе это противоречит мышлению «Реакт», поскольку состояние содержится внутри конкретного дочернего компонента, а не в компоненте DefaultComponent, который его обрабатывает.

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

Также см. Ответы на этот вопрос: http://stackoverflow.com/questions/22639534/pass-props-to-parent-component-in-react-js –

5

Чтобы выяснить, что steinso сказал, что вам нужно отправить событие в действие с помощью флюса архитектуры, а затем изменить его в магазине. Затем отправьте событие смены события с помощью EventEmitter. Это запустит рендер на обработанных компонентах с обновленным состоянием.

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

Если вы должны иметь их отделенное то, что будет лучшим способом. Однако, если вы можете иметь их в одном и том же компоненте, например «Главная», вы можете просто использовать атрибут ref и ссылаться на компонент.

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> 
    ); 
    } 

}); 

Словно так.

1

Я использую React с Material-UI, и я это сделал, используя событие onLeftIconButtonTouchTap = {this.handleToggle} в AppBar.Для более подробной информации, Вы можете обратиться официальной документации 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; 

Я думаю, что это поможет.

+0

Спасибо @Rohit Это помогло мне. Это то, что я ищу. –

 Смежные вопросы

  • Нет связанных вопросов^_^