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">×</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">×</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
- React入门记事本小项目(三)
- React入门记事本小项目(一)
- React入门记事本小项目(二)
- Android小项目:记事本
- Android小项目:记事本
- 我的记事本项目之路(三)
- react native (三) 入门基础知识
- React Native 入门(三)
- React Navigation 入门(三)
- 小记事本
- React 实践项目 (三)
- 【React Native】开源一个自己入门学习的小项目
- 【Facebook的UI开发框架React入门之三】第一个项目(iOS平台)-goodmao
- 记事本项目
- 谈谈小白react入门心理历程
- React小白入门---环境安装
- Python入门小项目
- VR小项目(三)
- 链表中倒数第k个结点
- 精通 CSS+DIV 网页样式与布局 79
- CC2541_simpleProfile_WriteAttrCB_simpleProfile_ReadAttrCB
- SPI驱动
- 最全ACM常用STL
- React入门记事本小项目(三)
- 精通 CSS+DIV 网页样式与布局 80
- 神经网络(二)
- 【每日一记】设计模式——建造者模式
- ZCMU—1774
- pm2 管理nodejs 日志存放问题
- Oracle materizlized view Study
- 关于dispose 方法的资源释放
- 多线程中的Join()方法