React入门记事本小项目(三)

来源:互联网 发布:mysql数据库设计 编辑:程序博客网 时间:2024/05/29 14:58

React入门记事本小项目的最后一部分,即完成反向数据流的添加,关于反向数据流的实现思想在我的另一篇文章:《React编程思想Demo解析》中也有所解释并有一个例子和流程图,可供参考。

六、添加反向数据流

这一步骤的目的在于,我们要将子组件的数据变化反向提供给父组件,然后父组件的state变化又上到下重新渲染页面,而因为React的单向数据流特性,改变父组件state的方法需要从父组件流向子组件,最顶层父组件App部分具体代码如下:
handleContentSubmit handleContentDelete handleContentEdit handleContentSelect分别负责对后台数据的增删改查,以及获得增删改查后的库中的数据。

/*整个App*/var App = React.createClass({  getInitialState: function () {    return {      INFOS: []    };  },  handleContentSubmit: function (content) {    var xmlhttp = new XMLHttpRequest();    var DataGet;    xmlhttp.onreadystatechange = function () {      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {        DataGet = xmlhttp.responseText;        DataGet = eval(DataGet);        for (var i = 0; i < DataGet.length; i++) {          DataGet[i].date = (new Date(DataGet[i].date)).toDateString();        }      }    }    content = encodeURI(encodeURI(content));    xmlhttp.open("GET", "http://localhost:8080/addData?content=" + content, false);    xmlhttp.send();    this.setState({      INFOS: DataGet    });  },  handleContentDelete: function (id) {    var xmlhttp = new XMLHttpRequest();    var DataGet;    xmlhttp.onreadystatechange = function () {      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {        DataGet = xmlhttp.responseText;        DataGet = eval(DataGet);        for (var i = 0; i < DataGet.length; i++) {          DataGet[i].date = (new Date(DataGet[i].date)).toDateString();        }      }    }    xmlhttp.open("GET", "http://localhost:8080/deleteData?id=" + id, false);    xmlhttp.send();    this.setState({      INFOS: DataGet    });  },  handleContentEdit: function (id, content) {    var xmlhttp = new XMLHttpRequest();    var DataGet;    xmlhttp.onreadystatechange = function () {      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {        DataGet = xmlhttp.responseText;        DataGet = eval(DataGet);        for (var i = 0; i < DataGet.length; i++) {          DataGet[i].date = (new Date(DataGet[i].date)).toDateString();        }      }    }    content = encodeURI(encodeURI(content));    xmlhttp.open("GET", "http://localhost:8080/editData?id=" + id + "&content=" + content, false);    xmlhttp.send();    this.setState({      INFOS: DataGet    });  },  handleContentSelect: function (content) {    var xmlhttp = new XMLHttpRequest();    var DataGet;    xmlhttp.onreadystatechange = function () {      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {        DataGet = xmlhttp.responseText;        DataGet = eval(DataGet);        for (var i = 0; i < DataGet.length; i++) {          DataGet[i].date = (new Date(DataGet[i].date)).toDateString();        }      }    }    content = encodeURI(encodeURI(content));    xmlhttp.open("GET", "http://localhost:8080/selectData?content=" + content, false);    xmlhttp.send();    this.setState({      INFOS: DataGet    });  },  componentDidMount: function () {    var xmlhttp = new XMLHttpRequest();    var DataGet;    xmlhttp.onreadystatechange = function () {      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {        DataGet = xmlhttp.responseText;        DataGet = eval(DataGet);        for (var i = 0; i < DataGet.length; i++) {          DataGet[i].date = (new Date(DataGet[i].date)).toDateString();        }      }    }    xmlhttp.open("GET", "http://localhost:8080/getData", false);    xmlhttp.send();    if (this.isMounted()) {      this.setState({        INFOS: DataGet      });    }  },  render: function () {    return (      <div className="container-fluid">        <div className="row">          <div className="col-md-10 col-md-offset-1">          <!-- 传向子组件 -->            <NavBar onContentSelect={this.handleContentSelect}/>            <AddModal onContentSubmit={this.handleContentSubmit}/>            <PanelList infos={this.state.INFOS} onContentDelete={this.handleContentDelete}                       onContentEdit={this.handleContentEdit}/>          </div>        </div>      </div>    );  }});

可以看到,父组件将改变自身的四个函数传到子组件,而后子组件再使用父组件提供的函数对父组件进行改变。子组件代码如下:

/*单个面板组件——包含其附属模态框*/var Panel = React.createClass({  handleDeleteClick: function () {    this.props.onContentDelete(this.props.contentId);  },  render: function () {    var modalId = "modal" + this.props.contentId;    var dataTarget = "#" + modalId;    var onContentEdit = this.props.onContentEdit;    return (      <div className="row">        <div className="col-md-12">          <div className="panel panel-success">            <div className="panel-heading">{this.props.heading}</div>            <div className="panel-body">              <div className="row">                <div className="col-md-10"><h4>{this.props.content}</h4></div>                <div className="col-md-2">                  <center>                    <button type="button" className="btn btn-default btn-sm" data-toggle="modal"                            data-target={dataTarget}>Edit                    </button>                    <button type="button" className="btn btn-default btn-sm" onClick={this.handleDeleteClick}>Delete                    </button>                  </center>                </div>              </div>            </div>          </div>          <EditModal contentId={this.props.contentId} content={this.props.content} onContentEdit={onContentEdit}/>        </div>      </div>    );  }});/*面板列表组*/var PanelList = React.createClass({  render: function () {    var panels = [];    var onContentDelete = this.props.onContentDelete;    var onContentEdit = this.props.onContentEdit;    this.props.infos.forEach(function (info) {      panels.push(        <Panel heading={info.date} content={info.content} contentId={info.id}               onContentDelete={onContentDelete} onContentEdit={onContentEdit}/>)    })    return (      <div id="panelList">        {panels}      </div>    );  }});/*导航条主体*/var NavBar = React.createClass({  render: function () {    var onContentSelect = this.props.onContentSelect;    return (      <nav className="navbar navbar-default" role="navigation">        <div className="container-fluid">          <NavBarHeader/>          <NavBarCollapse onContentSelect={onContentSelect}/>        </div>      </nav>    );  }});/*导航条头部*/var NavBarHeader = React.createClass({  render: function () {    return (      <div className="navbar-header">        <button type="button" className="navbar-toggle collapsed" data-toggle="collapse"                data-target="#navbar-collapse">          <span className="sr-only">Toggle navigation</span>          <span className="icon-bar"></span>          <span className="icon-bar"></span>          <span className="icon-bar"></span>        </button>        <a className="navbar-brand" href="#">Summery</a>      </div>    );  }});/*导航条内容*/var NavBarCollapse = React.createClass({  handleTextChange: function (e) {    this.props.onContentSelect(e.target.value);  },  render: function () {    return (      <div className="collapse navbar-collapse" id="navbar-collapse">        <form className="navbar-form navbar-right" role="search">          <div className="form-group">            <input type="text" className="form-control" placeholder="Search" onChange={this.handleTextChange}/>          </div>          <a className="btn btn-default" data-toggle="modal" data-target="#addModal">Add</a>        </form>      </div>    );  }});/*Add模态框*/var AddModal = React.createClass({  getInitialState: function () {    return {content: ""};  },  handleTextChange: function (e) {    this.setState({content: e.target.value});  },  //点击submit后的处理函数,其中content来自模态框的state  handleClick: function (e) {    e.preventDefault();    this.props.onContentSubmit(this.state.content);  },  render: function () {    return (      <div className="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"           aria-hidden="true">        <div className="modal-dialog">          <div className="modal-content">            <div className="modal-header">              <button type="button" className="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span                className="sr-only">Close</span></button>              <h4 className="modal-title">Today's summary</h4>            </div>            <div className="modal-body">              <form role="form">                <div className="form-group">                  <label for="inputContent">Today's summary:</label>                  <textarea type="text" className="form-control" placeholder="Enter today's summary"                            onChange={this.handleTextChange}/>                </div>              </form>            </div>            <div className="modal-footer">              <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>              <button type="button" className="btn btn-primary" value={this.state.content} onClick={this.handleClick} data-dismiss="modal">Submit</button>            </div>          </div>        </div>      </div>    );  }});/*Edit模态框*/var EditModal = React.createClass({  getInitialState: function () {    var defaultContent = this.props.content;    return {content: defaultContent};  },  handleTextChange: function (e) {    this.setState({content: e.target.value});  },  //点击submit后的处理函数,其中content来自模态框的state  handleClick: function (e) {    e.preventDefault();    this.props.onContentEdit(this.props.contentId, this.state.content);  },  render: function () {    var modalId = "modal" + this.props.contentId;    return (      <div className="modal fade" id={modalId} tabindex="-1" role="dialog" aria-labelledby="myModalLabel"           aria-hidden="true">        <div className="modal-dialog">          <div className="modal-content">            <div className="modal-header">              <button type="button" className="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span                className="sr-only">Close</span></button>              <h4 className="modal-title">Edit today's summary - id:{this.props.contentId}</h4>            </div>            <div className="modal-body">              <form role="form">                <div className="form-group">                  <label for="inputContent">Today's summary:</label>                  <textarea type="text" className="form-control" placeholder="Enter today's summary" value={this.state.content} onChange={this.handleTextChange}/>                </div>              </form>            </div>            <div className="modal-footer">              <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>              <button type="button" className="btn btn-primary" onClick={this.handleClick} data-dismiss="modal">Submit              </button>            </div>          </div>        </div>      </div>    );  }});ReactDOM.render(<App/>, document.getElementById("app"));

至此React部分的代码就完成了,后台服务器端servlet提供如下:
addDataServlet

package ajax;import com.alibaba.fastjson.JSON;import dao.HibernateUtil;import domain.SummaryEntity;import org.hibernate.Query;import org.hibernate.Session;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.net.URLDecoder;import java.sql.Date;import java.util.List;/** * Created by jutal on 16-11-16. */public class addDataServlet extends HttpServlet{    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String content = URLDecoder.decode(req.getParameter("content"), "UTF-8");        Session session = HibernateUtil.getSession();        session.beginTransaction();        SummaryEntity summaryEntity = new SummaryEntity();        java.util.Date date = new java.util.Date();        summaryEntity.setDate(new Date(date.getYear(), date.getMonth(), date.getDate()));        summaryEntity.setContent(content);        session.save(summaryEntity);        session.getTransaction().commit();        Query q = session.createQuery("from SummaryEntity ");        List<SummaryEntity> summaryEntityList = q.list();        String jsonString = JSON.toJSONString(summaryEntityList);        session.close();        resp.setContentType("application/json; charset=utf-8");        PrintWriter out = resp.getWriter();        out.append(jsonString);        out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {    }}

deleteDataServlet

package ajax;import com.alibaba.fastjson.JSON;import dao.HibernateUtil;import domain.SummaryEntity;import org.hibernate.Query;import org.hibernate.Session;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.util.List;/** * Created by jutal on 16-11-18. */public class deleteDataServlet extends HttpServlet{    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String id = req.getParameter("id");        Session session = HibernateUtil.getSession();        session.beginTransaction();        SummaryEntity summaryEntity = new SummaryEntity();        summaryEntity.setId(Integer.parseInt(id));        session.delete(summaryEntity);        session.getTransaction().commit();        Query q = session.createQuery("from SummaryEntity ");        List<SummaryEntity> summaryEntityList = q.list();        String jsonString = JSON.toJSONString(summaryEntityList);        session.close();        resp.setContentType("application/json; charset=utf-8");        PrintWriter out = resp.getWriter();        out.append(jsonString);        out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        super.doPost(req, resp);    }}

editDataServlet

package ajax;import com.alibaba.fastjson.JSON;import dao.HibernateUtil;import domain.SummaryEntity;import org.hibernate.Query;import org.hibernate.Session;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.net.URLDecoder;import java.util.Date;import java.util.List;/** * Created by jutal on 16-11-22. */public class editDataServlet extends HttpServlet{    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String content = URLDecoder.decode(req.getParameter("content"), "UTF-8");        int id = Integer.parseInt(req.getParameter("id"));        SummaryEntity summaryEntity = new SummaryEntity();        Date date = new Date();        summaryEntity.setId(id);        summaryEntity.setDate(new java.sql.Date(date.getYear(), date.getMonth(), date.getDate()));        summaryEntity.setContent(content);        Session session = HibernateUtil.getSession();        session.beginTransaction();        session.merge(summaryEntity);        session.getTransaction().commit();        Query q = session.createQuery("from SummaryEntity ");        List<SummaryEntity> summaryEntityList = q.list();        String jsonString = JSON.toJSONString(summaryEntityList);        session.close();        resp.setContentType("application/json; charset=utf-8");        PrintWriter out = resp.getWriter();        out.append(jsonString);        out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        super.doPost(req, resp);    }}

getDataServlet

package ajax;import com.alibaba.fastjson.JSON;import dao.HibernateUtil;import domain.SummaryEntity;import org.hibernate.Query;import org.hibernate.Session;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.util.List;/** * Created by jutal on 16-11-12. */public class getDataServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        Session session = HibernateUtil.getSession();        session.beginTransaction();        Query q = session.createQuery("from SummaryEntity");        List<SummaryEntity> summaryEntityList = q.list();        session.getTransaction().commit();        session.close();        resp.setContentType("application/json; charset=utf-8");        PrintWriter out = resp.getWriter();        String jsonString = JSON.toJSONString(summaryEntityList);        out.append(jsonString);        out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {    }}

selectDataServlet

package ajax;import com.alibaba.fastjson.JSON;import dao.HibernateUtil;import domain.SummaryEntity;import org.hibernate.Query;import org.hibernate.Session;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.net.URLDecoder;import java.util.List;/** * Created by jutal on 16-11-23. */public class selectDataServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String content = URLDecoder.decode(req.getParameter("content"), "UTF-8");        Session session = HibernateUtil.getSession();        session.beginTransaction();        Query query;        if (content.length() == 0) {            query = session.createQuery("from SummaryEntity");        } else {            //%(百分号):匹配任意类型、任意长度的字符串            query = session.createQuery("from SummaryEntity as S where S.content like '%" + content + "%'");        }        List<SummaryEntity> summaryEntityList = query.list();        String jsonString = JSON.toJSONString(summaryEntityList);        session.getTransaction().commit();        session.close();        resp.setContentType("application/json; charset=utf-8");        PrintWriter out = resp.getWriter();        out.append(jsonString);        out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        super.doPost(req, resp);    }}

其余相关配置文件可以在这个项目的github库中找到,在后台使用了hibernate及fastjson进行数据的处理,至此这个项目就基本完成了。

0 0