react.js CMS 删除功能的实现

页面效果图:

数据操作分析:

  1. 在查询表组件的  TableData.js 中操作如下内容:

    1. 给每一行绑定一个checkbox,且在点击这个 checkbox 时,触发 action 中的一个方法(formatPostCollectionList),这个方法是用来更新选中的实体数组。formatPostCollectionList为action中的方法,需要export

      1. 定义每一行的实体为一个数组,用变量 postCollections 表示
      2. 如果选中当前行,则更新实体数组中的数据;如果取消当前行,则删除实体中的数据;
      3. 参数为  row  ;
    2. 点击删除按钮后,使用 componentDitUpdate() 生命周期方法,在组件更新后调用。
      1. 如果删除成功,则执行 action 中的方法 clearPostCollection()。这个方法是用来清空当前行实体中的数据;
      2. 如果删除成功,最后执行  查询表的刷新重新加载数据的方法
  2. 更新实体数据与清空实体数据的方法,在 action 中执行。

代码分析:

  1. 表查询操作

    1. 调查询接口,Api中的方法

      1. searchPostCollectionByActivityId(activityId, callback) {
                const queryParam = `/tob/post/search?activeId=${activityId}`;   //接口,使用``可以在URL中显示查询参数
                Config.get(queryParam, callback);
            }
    2. action中操作查询数据的方法  postCollectionEntityList 存放接口中的所有数据
      1. export function initPostCollection(row){
            return (dispatch, getState) => {
                let activityId = row.activityId;
                Api.searchPostCollectionByActivityId(activityId, params => {
                    dispatch(initPostCollectionSetter(activityId,params));
                });
            }
        }
        function initPostCollectionSetter(activityId,params){
            return {
                type:INIT_POST_COLLECTION,
                activityId:activityId,
                data:{postCollectionEntityList:params}
            }
        }
    3. 3. TatleData 表组件中调用 action 的方法,至此 表数据 OK

      1. export default class TableData extends Component {
            constructor(props){
                super(props);
            }
        
            componentDidMount() {
                const param = this.props.queryData;
                console.log("param === " + param);
                this.props.initPostCollection(param);//action中获取接口数据的方法
            }
            render(){
               // 定义postCollectionEntityList中的数据
                let postCollectionEntityList = [
                    {
                        postCollectionName:‘‘,
                        postCollectionId:‘‘,
                        activityId:‘‘
                    }
                ];
                //判断,如果postCollectionEntityList中有数据,则把数据显示出来
                if (this.props.postCollectionState.postCollectionEntityList) {
                    postCollectionEntityList = this.props.postCollectionState.postCollectionEntityList;
                    console.log("postCollectionEntityList" + postCollectionEntityList);
                }
        
                //acb 表数据
                return(
                    <div><TableExit data={postCollectionEntityList} acb={this.props.initPostCollection}>
                            <TableCloumnsExit dataField="activityTitle">活动名称</TableCloumnsExit>
                            <TableCloumnsExit dataField="postCollectionName">帖子集名称</TableCloumnsExit>
                            <TableCloumnsExit dataField="postCollectionId">帖子集编号</TableCloumnsExit>
                            <TableCloumnsExit dataField="active" dataFormat={this.postCollectionFormatter}>修改</TableCloumnsExit>
                            <TableCloumnsExit dataField="send" dataFormat={this.activeFormatter.bind(this)}>发送</TableCloumnsExit>
                            <TableCloumnsExit dataField="send" dataFormat={this.questionBankFormatter.bind(this)}>题库</TableCloumnsExit>
                        </TableExit>
                    </div>
                );
            }
        }
  2. 删除表数据操作
    1. 调删除接口,API中的方法

      1. deletePostCollections (activityId ,params, callback) {
                let path = `/tob/post/deletePostCollection/${activityId}`;  //删除接口
                Config.deleteWithNoResponse(path ,params, callback);
            }
    2. action 中写删除数据的方法
      1. 删除实体

        1. 删除实体前要先 插入 checkbox

          1.  checkboxFormatter(cell,row) {
                    return <input bsStyle="primary" type="checkbox"></input>
                }
        2. 查询表中使用 checkbox
          1. <TableCloumnsExit dataField="alter" dataFormat={this.checkboxFormatter.bind(this)}>选择</TableCloumnsExit>
        3. 点击 checkbox 会触发 更新选中的实体数据的方法
          1. checkboxFormatter(cell,row) {
                    return <input bsStyle="primary" type="checkbox" onClick={this.props.formatPostCollectionList.bind(this,row)}></input>
                }
        4. 更新选中实体数据的方法,在action中编写
          1. export function formatPostCollectionList(row) {
                return(dispatch, getState) => {
                    let postCollectionId = row.postCollectionId;  //获取每一行的ID
                    let state = getState().postCollectionState;   //从postCollectionState()中拿到state并赋值给全局state
                    let postCollections = state.postCollections;  // 红色字体标注为实体中的数据容器
                    let postCollectionItem = {
                        postCollectionId:postCollectionId         //实体中的数据ID
                    };
                    if (postCollections) {   //postCollections 实体数据,可能 有数据
                        let index = -1;      // index = -1 指默认实体中没有数据
                        for (let i = 0 ;i < postCollections.length ;i++) { //如果实体中有数据,则循环
                            let postCollection = postCollections[i];       //拿实体中的数据,给变量postCollection
                            let id = postCollection.postCollectionId;      //从拿到的实体数据中,取每一个ID,方法对比(选中的数据与实体中的数据对比)
                            if (postCollectionId == id) {  //如果实体中的ID == 选中的ID
                                index = i;                 //把实体中选中的的数据 赋值为 i
                            }
                        }
                        if (index > -1) {                 //如果实体的数据存在,不为空
                            postCollections.splice(index,1);   //删除实体对象中index位置中的一个数据
                        } else {
                            postCollections.push(postCollectionItem);  //如果实体数据为空,则push实体中的ID数据
                        }
                    } else {
                        postCollections = [];  // 第一次render时,实体数据可能为空 / 为undefined,那么将它定义为一个数组
                        postCollections.push(postCollectionItem);   //给这个空数组push数据
                    }
                    dispatch(formatPostCollectionListSetter(postCollections));
                }
            }
            function formatPostCollectionListSetter(params){
                return {
                    type:SET_POST_COLLECTIONS,
                    data:{postCollections:params}  //红色变量为实体数据
                }
            }
        5. 选中实体数据后,点击删除按钮,会触发deletePostCollections  删除方法
        6. export const DELETE_POST_COLLECTIONS = ‘DELETE_POST_COLLECTIONS‘;
          export function deletePostCollections(){   //点击删除按钮后,触发deletePostCollections删除方法
              return(dispatch, getState) => {
                  let state = getState().postCollectionState;
                  let activityId = state.activityId;
                  let postCollections = state.postCollections;  //实体对象从state中获取
                  Api.deletePostCollections(activityId ,postCollections, params => {   //调删除接口的方法
                      dispatch(deletePostCollectionsSetter(params));
                  });
              }
          }
          function deletePostCollectionsSetter(params){
              alertPre("",params);
              return {
                  type:DELETE_POST_COLLECTIONS,
                  data:{deletePostCollectionsResponse:params}  //deletePostCollectionsResponse  选中的要删除的数据容器
              }
          }

          6. 把删除数据的方法绑定到删除按钮,绑定前根据删除钮钮的状态,判断是否可点击

        7. render(){
                  let dis = true;  //删除按钮状态,默认为禁用状态,返回为true
                  let postCollections = this.props.postCollectionState.postCollections;  //获取实体中的数据
                  if (typeof(postCollections) == ‘undefined‘ || postCollections.length == 0) {   //如果实体中的数据为 undefined 或者 为空
                      dis = true;  //如果实体中没有数据,则按钮状态为禁用状态
                  } else {
                      dis = false;  //如果实体中有数据,选中后的状态为可点击状态
                  }
          
                  const buttonsInstanceDel = (
                      <ButtonToolbar className="mb10">
                          <Button bsStyle="danger" disabled={dis} onClick={this.props.deletePostCollections}>删除贴子集</Button>  //红色字体标为  删除数据的方法
                      </ButtonToolbar>
                  );
          
                  return(
                      <div>
                          {buttonsInstanceDel}
                      </div>
                  )
              }

          7.  删除成功后,调用生命周期的方法,在 表查询组件中,更新表数据。如果删除成功,则执行两个方法:清空实体数据与刷新加载数据

        8. componentDidUpdate () {
                  let deletePostCollectionsResponse = this.props.postCollectionState.deletePostCollectionsResponse;  //deletePostCollectionsResponse 删除的数据
                  if (typeof(deletePostCollectionsResponse) != ‘undefined‘) { //如果这个数据类型不是 undefined
                      let status = deletePostCollectionsResponse.status;      //获取到这个删除的数据状态
                      if (200 == status) {                                    //如果为200,删除成功
                          this.props.clearPostCollection();                   //加载清空实体数据的方法 clearPostCollection,就是从实体数据中删除被删除的数据
                          let param = {
                              activityId:this.props.postCollectionState.activityId
                          }
                          this.props.initPostCollection(param);              //根据ID重新加载剩余的数据
                      }
                  }
              }
      2. 清空实体
        1. export const CLEAR_POST_COLLECTION = ‘CLEAR_POST_COLLECTION‘;
          export function clearPostCollection(){
              return {
                  type: CLEAR_POST_COLLECTION,
                  data:{   //实体中的数据名称
                      addPostCollectionResponse:{},
                      postCollections:[],
                      deletePostCollectionsResponse:{},
                      postCollectionName:‘‘,
                      postNumber:‘0‘,
                      postFieldList:[]
                  }
              }
          }
  3. 所有代码结构,含一个api,一个action,两个component,一个reducers
  • api(查询 / 删除)
//查询
searchPostCollectionByActivityId(activityId, callback) {
        const queryParam = `/tob/post/search?activeId=${activityId}`;
        Config.get(queryParam, callback);
    }

//删除
deletePostCollections (activityId ,params, callback) {
        let path = `/tob/post/deletePostCollection/${activityId}`;
        Config.deleteWithNoResponse(path ,params, callback);
    }
  • action(查询方法 / 更新选中实体数据方法 / 删除方法 / 清空实体数据方法 )
//查询表数据
export function initPostCollection(row){
    return (dispatch, getState) => {
        let activityId = row.activityId;
        Api.searchPostCollectionByActivityId(activityId, params => {
            dispatch(initPostCollectionSetter(activityId,params));
        });
    }
}
function initPostCollectionSetter(activityId,params){
    return {
        type:INIT_POST_COLLECTION,
        activityId:activityId,
        data:{postCollectionEntityList:params}
    }
}

//更新选中实体数据
export function formatPostCollectionList(row) {
    return(dispatch, getState) => {
        let postCollectionId = row.postCollectionId;
        let state = getState().postCollectionState;
        let postCollections = state.postCollections;
        let postCollectionItem = {
            postCollectionId:postCollectionId
        };
        if (postCollections) {
            let index = -1;
            for (let i = 0 ;i < postCollections.length ;i++) {
                let postCollection = postCollections[i];
                let id = postCollection.postCollectionId;
                if (postCollectionId == id) {
                    index = i;
                }
            }
            if (index > -1) {
                postCollections.splice(index,1);
            } else {
                postCollections.push(postCollectionItem);
            }
        } else {
            postCollections = [];
            postCollections.push(postCollectionItem);
        }
        dispatch(formatPostCollectionListSetter(postCollections));
    }
}
function formatPostCollectionListSetter(params){
    return {
        type:SET_POST_COLLECTIONS,
        data:{postCollections:params}
    }
}

//删除方法
export const DELETE_POST_COLLECTIONS = ‘DELETE_POST_COLLECTIONS‘;
export function deletePostCollections(){
    return(dispatch, getState) => {
        let state = getState().postCollectionState;
        let activityId = state.activityId;
        let postCollections = state.postCollections;
        Api.deletePostCollections(activityId ,postCollections, params => {
            dispatch(deletePostCollectionsSetter(params));
        });
    }
}
function deletePostCollectionsSetter(params){
    alertPre("",params);
    return {
        type:DELETE_POST_COLLECTIONS,
        data:{deletePostCollectionsResponse:params}
    }
}

//清空实体数据
export const CLEAR_POST_COLLECTION = ‘CLEAR_POST_COLLECTION‘;
export function clearPostCollection(){
    return {
        type: CLEAR_POST_COLLECTION,
        data:{
            addPostCollectionResponse:{},
            postCollections:[],
            deletePostCollectionsResponse:{},
            postCollectionName:‘‘,
            postNumber:‘0‘,
            postFieldList:[]
        }
    }
}
  • component(BtnDelData.js / TableData.js (checkbox))
//删除按钮组件
import React,{Component} from ‘react‘;
import {render} from ‘react-dom‘;
import ReactBootstrap , {ButtonToolbar,Button,Pagination} from ‘react-bootstrap‘;

export default class BtnDelData extends Component {
    constructor(props){
        super(props);
    }

    render(){
        let dis = true;
        let postCollections = this.props.postCollectionState.postCollections;
        if (typeof(postCollections) == ‘undefined‘ || postCollections.length == 0) {
            dis = true;
        } else {
            dis = false;
        }

        const buttonsInstanceDel = (
            <ButtonToolbar className="mb10">
                <Button bsStyle="danger" disabled={dis} onClick={this.props.deletePostCollections}>删除贴子集</Button>
            </ButtonToolbar>
        );

        return(
            <div>
                {buttonsInstanceDel}
            </div>
        )
    }
}

//表组件
import React, {Component} from ‘react‘;
import {render} from ‘react-dom‘;
import ReactBootstrap , {ButtonToolbar,Button,Pagination,Grid,Row,Col} from ‘react-bootstrap‘;
import { Router, Route, IndexRoute, Link, IndexLink, browserHistory } from ‘react-router‘;
const ACTIVE = { color: ‘red‘ };
import {sessionSetItem,sessionGetItem} from ‘storage‘;

import BtnAddData from ‘./BtnAddData.js‘;
import BtnDelData from ‘./BtnDelData.js‘;

//引用公共组件
import TableExit from ‘public_component/table/TableExit.js‘;
import TableCloumnsExit from ‘public_component/table/TableCloumnsExit.js‘;

//跳转路径
import {invitation_main_path,post_collection_main_path,activity_main_path,question_bank_main_path} from ‘/build/config.js‘;

export default class TableData extends Component {
    constructor(props){
        super(props);
    }

    componentDidMount() {
        const param = this.props.queryData;
        console.log("param === " + param);
        this.props.initPostCollection(param);
    }

    componentDidUpdate () {
        let deletePostCollectionsResponse = this.props.postCollectionState.deletePostCollectionsResponse;
        if (typeof(deletePostCollectionsResponse) != ‘undefined‘) {
            let status = deletePostCollectionsResponse.status;
            if (200 == status) {
                this.props.clearPostCollection();
                let param = {
                    activityId:this.props.postCollectionState.activityId
                }
                this.props.initPostCollection(param);
            }
        }
    }

    //修改
    activeFormatter(cell,row) {
        return <Button bsStyle="primary" onClick={this.props.sendPostCollection.bind(null,row)}>推送</Button>

    }

    checkboxFormatter(cell,row) {
        return <input bsStyle="primary" type="checkbox" onClick={this.props.formatPostCollectionList.bind(this,row)}></input>
    }

    //修改
    postCollectionFormatter(cell,row) {
        return <Link to={{ pathname:post_collection_main_path, query: row}} activeStyle={ACTIVE}>修改</Link>
    }

    questionBankFormatter(cell,row) {
        return <Link to={{ pathname: question_bank_main_path, query: row}} activeStyle={ACTIVE} >查看题库</Link>
    }

    render(){

        let postCollectionEntityList = [
            {
                postCollectionName:‘‘,
                postCollectionId:‘‘,
                activityId:‘‘
            }
        ];

        if (this.props.postCollectionState.postCollectionEntityList) {
            postCollectionEntityList = this.props.postCollectionState.postCollectionEntityList;
            console.log("postCollectionEntityList" + postCollectionEntityList);
        }

        //let postCollectionEntityList = this.props.postCollectionState.postCollectionEntityList;

        //添加与删除
        const gridInstance = (
            <Grid className="mb5">
                <Row className="show-grid">
                    <Col sm={1} mdPush={-7}><BtnAddData {...this.props} activityParam={this.props.queryData} /></Col>
                    <Col sm={1}><BtnDelData {...this.props} /></Col>
                </Row>
            </Grid>
        );

        //acb 表数据
        return(
            <div>
               {gridInstance}
                <TableExit data={postCollectionEntityList} acb={this.props.initPostCollection}>
                    <TableCloumnsExit dataField="alter" dataFormat={this.checkboxFormatter.bind(this)}>选择</TableCloumnsExit>
                    <TableCloumnsExit dataField="activityTitle">活动名称</TableCloumnsExit>
                    <TableCloumnsExit dataField="postCollectionName">帖子集名称</TableCloumnsExit>
                    <TableCloumnsExit dataField="postCollectionId">帖子集编号</TableCloumnsExit>
                    <TableCloumnsExit dataField="active" dataFormat={this.postCollectionFormatter}>修改</TableCloumnsExit>
                    <TableCloumnsExit dataField="send" dataFormat={this.activeFormatter.bind(this)}>发送</TableCloumnsExit>
                    <TableCloumnsExit dataField="send" dataFormat={this.questionBankFormatter.bind(this)}>题库</TableCloumnsExit>
                </TableExit>
                <ButtonToolbar>
                    <Link className="btn btn-primary" to={{ pathname:activity_main_path}}>返回到活动界面</Link>
                </ButtonToolbar>
            </div>
        );
    }
}
  • reducers (state合并)

以上为删除功能的用法。

时间: 2024-10-11 08:31:11

react.js CMS 删除功能的实现的相关文章

通过js实现删除功能 ruby on rails

(1)首先给删除按钮增加一个属性 remote: true,这样ujs将这个click动作转化为ajax调用, app/views/products/_product.html.erb <tr id="product_<%= product.id %>"> <td><%= link_to product.id, product_path(product) %></td> <td id="product_<

前端迷思与React.js

前端迷思与React.js 前端技术这几年蓬勃发展, 这是当时某几个项目需要做前端技术选型时, 相关资料整理, 部分评论引用自社区. 开始吧: 目前, Web 开发技术框架选型为两种的占 80% .这种戏剧性的变化持续了近 6 年. 自 2013 年 5 月推出以来,ReactJS 在过去三年中已成为了 Web 开发领域的中坚力量. 任何组件与框架都有它的适用场景, 我们应该冷静分析与权衡, 先来看React.js 1 从功能开发角度说,React的思路很好.2 从页面设计角度说,传统的HTML

react.js 之 create-react-app 命令行工具系统讲解

react.js 教程之 create-react-app 命令行工具系统讲解 快速开始 npm install -g create-react-app create-react-app my-app cd my-app/ npm start 通过http://localhost:3000/查看你的app 使用 npm run build 编译打包程序 npm test 文件修改后测试,这部分内容后面讲 更新到最新版本 创建react app的主要分为两个包,一个包是create-react-a

React.js再探(四)

不知道看官们还记不记得上一节的内容,关于生命周期的.我们来个例子重温且练习一下. 传送门:http://www.cnblogs.com/galenyip/p/4574400.html 我们来实现一下时钟的功能,要求当秒是“0”的时候,字体变为红色.注意用componentWillUpdate实现. 如       当秒是0   变为 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8&qu

React.js小书总结

(迁移自旧博客2017 08 27) 第一阶段 react的组件相当于MVC里面的View. react.js 将帮助我们将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合.嵌套,就成了我们的页面. react.js 不是一个框架,它只是一个库.它只提供 UI (view)层面的解决方案.在实际的项目当中,它并不能解决我们所有的问题,需要结合其它的库,例如 Redux.React-router 等来协助提供完整的解决方法. 组件化可以帮助我们解决前端结构的复用性问题,整个页面可以

使用EasyUI实现添加和删除功能

        增删该查是任何一个项目都少不了的功能操作,这篇博文主要简介一下如何使用EasyUI实现添加和删除功能.         首先,导入EasyUI的js代码: <link href="~/EasyuiSource/themes/default/easyui.css" rel="stylesheet" /> <link href="~/EasyuiSource/themes/icon.css" rel="st

UEditor 添加在线管理图片删除功能

第一,需要添加一个 php 文件来实现删除功能,文件添加到: ueditor\php\action_delete.php 代码内容: <?php   /*---------------------------  * wang  *zhibeiwang.blog.51cto.com  * 2017-08-10  * action_delete.php  * 删除 Ueditor 目录下的文件  *---------------------------*/   try {     //获取路径   

Angular、React.js 和Node.js到底选谁?

为了工作,程序员选择正确的框架和库来构建应用程序是至关重要的,这也就是为什么Angular和React之间有着太多的争议.Node.js的出现,让这场战争变得更加复杂,虽然有选择权通常是一件很棒的事情,但在这种情况下,对于到底应该选择哪种框架,程序员之间并没有一致的意见,每个人都有不同的想法,并且听起来都相当合理. 为了让一切归于和谐,本文就来探究一下这三大框架各自的优缺点. 基础知识部分: 在我们深入研究这三种框架的具体细节之前,先来了解一些前情提要.yigouyul22.com xucaiz

ajax中网页传输(一)TEXT——带有删除功能的数据库表格显示练习

网页之间传输的三种方式:TEXT.JSON.XML. 本章将讲解带有TEXT形势的ajax网页传输 第一:body部分代码 <title>ajax中TEXT讲解并且带有删除功能的表格</title> <script src="jquery-2.0.0.min.js"></script> <style type="text/css"> .sc { width:70px; height:30px; backgr