web-dev-qa-db-fra.com

Interface utilisateur des matériaux - Ouvrez LeftNav/Drawer sur AppBar, cliquez sur

Je découvre ReactJS et material-ui ( http://material-ui.com/ ).

J'essaie de créer un modèle par défaut pour mon application ..__ Je souhaite utiliser un AppBar et un LeftNav (renommé dans Drawer dans les nouvelles versions) dans des composants séparés.

La barre d’application possède un bouton de menu par défaut. Je veux l'utiliser pour ouvrir LeftNav mais je ne sais pas comment appeler ma fonction de composant LeftBarComponent pour l'ouvrir.

J'ai presque compris comment communiquer entre les composants mais dans mon cas, je ne sais pas comment je pourrais le faire car il n'existe aucune documentation à ce sujet .. La seule chose que je sache pour ouvrir l'élément LeftNav est d'utiliser LeftNav. basculer() 

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

Merci de votre aide.

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;
17
T00rk

Dans ce cas, vous devez transmettre l'événement à travers vos composants, puis à nouveau.

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

Cependant, l’utiliser conjointement avec Reactjs n’est pas optimal, car le composant matériel LeftNav ne réagit pas aux attributs, mais aux appels de méthode comme vous le disiez. 

Pour contourner le problème, vous pouvez cocher la méthode de rendu LeftNav, vérifier l'état actuel et appeler toggle () si nécessaire. En principe, cela va à l’encontre de la façon de penser React, puisqu'un état est contenu dans le composant enfant spécifique et non dans le composant DefaultComponent qui le gère.

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

Pour clarifier ce que steinso a dit, vous devez envoyer l'événement à une action utilisant l'architecture Flux, puis le modifier dans un magasin. Puis envoyez un événement emit change avec EventEmitter. Cela déclenchera un rendu sur les composants affectés avec l'état mis à jour.

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

Si vous devez les séparer, ce serait la meilleure solution. Cependant, si vous pouvez les avoir dans le même composant, tel que "Main", vous pouvez simplement utiliser un attribut ref et référencer le composant.

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

});

Ainsi.

5
dbarth

J'utilise React avec Material-UI et je l'ai fait avec l'événement onLeftIconButtonTouchTap = {this.handleToggle} dans AppBar. Pour plus de détails, vous pouvez vous référer à la documentation officielle 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;

Je pense que cela vous aidera.

1
Rohit Luthra