2015-02-24 14 views
15

Tôi đang khám phá ReactJS và material-ui (http://material-ui.com/).Giao diện người dùng Material - Mở LeftNav/Drawer trên AppBar nhấp

Tôi cố gắng tạo mẫu mặc định cho ứng dụng của mình. Tôi muốn sử dụng một AppBar và LeftNav (được đổi tên trong Ngăn kéo trong phiên bản mới) trong các thành phần được tách riêng.

AppBar có nút menu trên đó theo mặc định. Tôi muốn sử dụng nó để mở LeftNav nhưng tôi không biết làm thế nào tôi có thể gọi chức năng thành phần LeftBarComponent của tôi để mở nó.

Tôi gần như đã hiểu cách giao tiếp giữa các thành phần nhưng trong trường hợp của tôi, tôi không biết làm thế nào tôi có thể làm vì không có tài liệu về nó. Điều duy nhất mà tôi biết để mở các yếu tố LeftNav là sử dụng LeftNav.toggle()

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

Nhờ sự giúp đỡ của bạn.

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; 

Trả lời

5

Trong trường hợp này bạn nee d để vượt qua sự kiện trở lên thông qua các thành phần của bạn, và sau đó xuống một lần nữa.

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

Tuy nhiên, việc sử dụng kết hợp này với Reactj không phải là tối ưu, vì thành phần vật liệu LeftNav không phản ứng với thuộc tính, nhưng đối với các cuộc gọi phương thức như bạn đang nói.

Để làm việc xung quanh, bạn có thể đặt dấu kiểm trong phương thức hiển thị LeftNav, kiểm tra trạng thái hiện tại và chuyển đổi cuộc gọi() nếu cần. Về nguyên tắc điều này đi ngược lại cách suy nghĩ phản ứng, như một trạng thái được chứa bên trong thành phần con cụ thể và không nằm trong DefaultComponent xử lý nó.

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

Đồng thời xem câu trả lời cho câu hỏi này: http://stackoverflow.com/questions/22639534/pass-props-to-parent-component-in-react-js –

5

Để làm rõ những gì steinso đã nói, bạn cần gửi sự kiện đến Hành động bằng kiến ​​trúc Flux và sau đó thay đổi nó trong Cửa hàng. Sau đó gửi một sự kiện thay đổi phát ra bằng EventEmitter. Điều này sẽ kích hoạt kết xuất trên các thành phần có hiệu lực với trạng thái được cập nhật.

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

Nếu bạn phải tách riêng thì đó là cách tốt nhất. Tuy nhiên, nếu bạn có thể có chúng trong cùng một thành phần, chẳng hạn như 'Chính' thì bạn chỉ có thể sử dụng thuộc tính ref và tham chiếu thành phần.

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

}); 

Giống như vậy.

1

Tôi đang sử dụng React với Material-UI và tôi đã thực hiện điều này bằng cách sử dụng onLeftIconButtonTouchTap = {this.handleToggle} sự kiện trong AppBar.Để cụ thể hơn, bạn có thể tham khảo tài liệu chính thức 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; 

Tôi nghĩ rằng nó sẽ giúp bạn.

+0

Cảm ơn @Rohit Nó đã giúp tôi. Đây là những gì tôi đang tìm kiếm. –

Các vấn đề liên quan