如何通过用户选择实现添加方法?

时间:2019-04-02 18:17:19

标签: reactjs

我的应用程序中有一个add方法。单击窗口小部件后,您便可以添加另一个窗口小部件。当前添加的默认组件是,但我希望用户能够从组件列表中进行选择。我是新来的,任何帮助都会很棒。

import React, { Component } from 'react';
import Swappable from './components/SwappableComponent'
import './App.css';
import DataTable from './components/tableWidget';
import CheckboxList from './components/CheckboxList';
import AddWidgetDialog from './components/AddWidgetDialog';
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";
import { Table } from '@material-ui/core';



const styles = theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    padding: theme.spacing.unit * 2,
    textAlign: "center",
    color: theme.palette.text.secondary
  }
});

class App extends Component {
    constructor(props) {
      super(props);
      this.state={

        widgetOptions:[{name:"Data Table", comp:<DataTable/>},{name:"List", comp:<CheckboxList/>}],

        widgets:[ //array for layout 
          {id:1, content: <DataTable/>},
          {id:2, content: <CheckboxList/>},
          {id:3, content: ""},
          {id:4, content: ""}
        ],
        isModalOpen: false
      }

    }  
    deleteEvent=(index)=>{
        const copyWidgets=Object.assign([],this.state.widgets);
        let widget=this.state.widgets[index];
        widget.content="";
        copyWidgets[index]=widget;
        this.setState({
            widgets:copyWidgets
        })
    }
    addEvent=(index)=>{
        this.setState({isModalOpen: true})
        const copyWidgets=Object.assign([],this.state.widgets);
        let widget=this.state.widgets[index];
        widget.content=<DataTable/>; 
        copyWidgets[index]=widget;
        this.setState({
            widgets:copyWidgets
        })
    }
    onRequestClose = () => {
        this.setState({
          isModalOpen: false,
        });
      }
    render() {
      const { classes } = this.props;

      return (

      <div className={classes.root}>
      <AddWidgetDialog widgets={this.state.widgetOptions} isModalOpen={this.state.isModalOpen} onRequestClose={this.onRequestClose} />
        <Grid container spacing={24}>
            {
                this.state.widgets.map((widget,index)=>{
                    return(
                        <Grid item xs={12} sm={6}>
                            <Paper className={classes.paper}><Swappable id={widget.id} content={widget.content} delete={this.deleteEvent.bind(this,index)} add={this.addEvent.bind(this,index)}/></Paper>
                         </Grid>
                    )
                })
            }
        </Grid>
      </div>
      );
    }
  }

  App.propTypes = {
    classes: PropTypes.object.isRequired
  };

  export default withStyles(styles)(App);

这是我的app.js,其中包含小部件和添加事件:

import React, { PropTypes } from 'react';
import Modal from 'react-modal';

const AddWidgetDialog = ({ widgets, isModalOpen, onRequestClose}) => {
  const widgetItems = Object.keys(widgets).map((widget, key) => {
    return (
      <div key={key} className="list-group">
      <a href="#" className="list-group-item">
          <h6 className="list-group-item-heading">{widgets[widget].name}</h6>
        </a>
      </div>
    );
  });
  return (
    <Modal
      className="Modal__Bootstrap modal-dialog"
      isOpen={isModalOpen}>
      <div className="modal-content">
       <div className="modal-header">
         <button type="button" className="close" onClick={onRequestClose}>
           <span aria-hidden="true">&times;</span>
           <span className="sr-only">Close</span>
         </button>
         <h4 className="modal-title">Add a widget</h4>
       </div>
       <div className="modal-body">
         <h5>Pick a widget to add</h5>
         {widgetItems}
       </div>
       <div className="modal-footer">
         <button type="button" className="btn btn-default" onClick={onRequestClose}>Close</button>
       </div>
      </div>
    </Modal>
  );
};


export default AddWidgetDialog;

这是我的模态:

onFinished

1 个答案:

答案 0 :(得分:1)

我不确定我是否理解得很好,但总的来说,我会做这样的事情:

function compGallery(picked) {
  switch(picked) {
    case "ListWidget": return <ListWidget />
    case "Table": return <Table />
    ...
    default: return <DataTable />
  }
}

然后,我将创建一个列表组件,用户可以在其中选择,该处理程序将调用this.setState({ pickedComponent })

并在您的方法中使用它:

addEvent=(index)=>{
        this.setState({isModalOpen: true})
        const copyWidgets=Object.assign([],this.state.widgets);
        let widget=this.state.widgets[index];
        widget.content=compGalery(this.state.pickedComponent); 
        copyWidgets[index]=widget;
        this.setState({
            widgets:copyWidgets
        })
    }

希望对您有帮助。

问题更新后,这里是我的建议

我们将处理程序作为道具handleWidgetSelection

传递
const AddWidgetDialog = ({ handleWidgetSelection, widgets, isModalOpen, onRequestClose}) => {
  const widgetItems = Object.keys(widgets).map((widget, key) => {
    return (
      <div key={key} className="list-group">
      <a href="#" onClick={() => handleWidgetSelection(widget.name)} className="list-group-item">
          <h6 className="list-group-item-heading">{widgets[widget].name}</h6>
        </a>
      </div>
    );
  });
  return (
    <Modal
      className="Modal__Bootstrap modal-dialog"
      isOpen={isModalOpen}>
      <div className="modal-content">
       <div className="modal-header">
         <button type="button" className="close" onClick={onRequestClose}>
           <span aria-hidden="true">&times;</span>
           <span className="sr-only">Close</span>
         </button>
         <h4 className="modal-title">Add a widget</h4>
       </div>
       <div className="modal-body">
         <h5>Pick a widget to add</h5>
         {widgetItems}
       </div>
       <div className="modal-footer">
         <button type="button" className="btn btn-default" onClick={onRequestClose}>Close</button>
       </div>
      </div>
    </Modal>
  );
};

在这里,我们可以定义更新selectedWidgetId的处理程序,该处理程序基本上是您在模态中选择的项,一旦我们知道要显示哪个组件即可显示

import React, { Component } from 'react';
import Swappable from './components/SwappableComponent'
import './App.css';
import DataTable from './components/tableWidget';
import CheckboxList from './components/CheckboxList';
import AddWidgetDialog from './components/AddWidgetDialog';
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";
import { Table } from '@material-ui/core';



const styles = theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    padding: theme.spacing.unit * 2,
    textAlign: "center",
    color: theme.palette.text.secondary
  }
});

class App extends Component {
    constructor(props) {
      super(props);
      this.state={
        selectedWidgetId: "Data Table",
        widgetOptions:[{name:"Data Table", comp:<DataTable/>},{name:"List", comp:<CheckboxList/>}],

        widgets:[ //array for layout 
          {id:1, content: <DataTable/>},
          {id:2, content: <CheckboxList/>},
          {id:3, content: ""},
          {id:4, content: ""}
        ],
        isModalOpen: false
      }

    }
    handleWidgetSelection=(id) => {
      this.setState({selectedWidgetId: id})
    }
    deleteEvent=(index)=>{
        const copyWidgets=Object.assign([],this.state.widgets);
        let widget=this.state.widgets[index];
        widget.content="";
        copyWidgets[index]=widget;
        this.setState({
            widgets:copyWidgets
        })
    }
    addEvent=(index)=>{
        this.setState({isModalOpen: true})
        const copyWidgets=Object.assign([],this.state.widgets);
        let widget=this.state.widgets[index];
        widget.content=this.state.widgetOptions.find(w => w.name === this.state.selectedWidgetId).comp; 
        copyWidgets[index]=widget;
        this.setState({
            widgets:copyWidgets
        })
    }
    onRequestClose = () => {
        this.setState({
          isModalOpen: false,
        });
      }
    render() {
      const { classes } = this.props;

      return (

      <div className={classes.root}>
      <AddWidgetDialog handleWidgetSelection={this.handleWidgetSelection} widgets={this.state.widgetOptions} isModalOpen={this.state.isModalOpen} onRequestClose={this.onRequestClose} />
        <Grid container spacing={24}>
            {
                this.state.widgets.map((widget,index)=>{
                    return(
                        <Grid item xs={12} sm={6}>
                            <Paper className={classes.paper}><Swappable id={widget.id} content={widget.content} delete={this.deleteEvent.bind(this,index)} add={this.addEvent.bind(this,index)}/></Paper>
                         </Grid>
                    )
                })
            }
        </Grid>
      </div>
      );
    }
  }

  App.propTypes = {
    classes: PropTypes.object.isRequired
  };

  export default withStyles(styles)(App);