Material UI - 在 AppBar 点击打开 LeftNav / Drawer
Posted
技术标签:
【中文标题】Material UI - 在 AppBar 点击打开 LeftNav / Drawer【英文标题】:Material UI - Open LeftNav / Drawer on AppBar click 【发布时间】:2015-04-25 20:23:44 【问题描述】:我正在发现 ReactJS 和 material-ui (http://material-ui.com/)。
我尝试为我的应用程序创建一个默认模板。 我想在单独的组件中使用 AppBar 和 LeftNav(在新版本的 Drawer 中重命名)。
默认情况下,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;
【问题讨论】:
【参考方案1】:在这种情况下,您需要通过组件向上传递事件,然后再向下传递。
<MainNavbar onClickMenu=this.onClickMenu/>
<LeftNavbar isOpen=this.state.leftNavIsOpen/>
但是,将它与 Reactjs 结合使用并不是最佳选择,因为 LeftNav 材质组件不会对属性做出反应,而是对方法调用做出反应,就像你说的那样。
要解决此问题,您可以检查 LeftNav 渲染方法,该方法检查当前状态,并在需要时调用 toggle()。原则上这违背了 React 的思维方式,因为状态包含在特定的子组件中,而不是在处理它的 DefaultComponent 中。
render:function()
if(this.props.isOpen)
LeftNav.open();
return ...
【讨论】:
另请参阅此问题的答案:***.com/questions/22639534/…【参考方案2】:为了澄清 steinso 所说的,您需要使用 Flux 架构将事件发送到 Action,然后在 Store 中更改它。然后使用 EventEmitter 调度一个发出更改事件。这将在具有更新状态的受影响组件上触发渲染。
https://facebook.github.io/flux/
如果您必须将它们分开,那将是最好的方法。但是,如果您可以将它们放在同一个组件中,例如“Main”,那么您可以简单地使用 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>
);
);
像这样。
【讨论】:
【参考方案3】:我正在将 React 与 Material-UI 一起使用,并且我已使用 AppBar 中的 onLeftIconButtonTouchTap=this.handleToggle 事件来完成此操作。更详细的可以参考官方文档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;
我想它会对你有所帮助。
【讨论】:
谢谢@Rohit 它帮助了我。这就是我要找的。span>以上是关于Material UI - 在 AppBar 点击打开 LeftNav / Drawer的主要内容,如果未能解决你的问题,请参考以下文章
Material UI Drawer 不会在 Appbar 下移动
如何向 Material-UI 的 AppBar 组件添加多个元素?