Thinkphp5 ajax批量删除功能的实现(记录下自己走过的坑)

在学习Thinkphp5过程中,做到批量删除功能时,本以为可以象sql语句中的update、delete一样,可以批量操作,在网上查找了资料,但看很多都用的是循环。而TP5资料上说的可是有update和saveAll语句啊。由于用ajax,所以就先按照网络上大家说的用循环先做,随后再试TP5的update和saveAll语句吧。

这样,根据网络上的资料,就按照做列表页面、写脚本及ajax、最后写控制器这个步骤来做。

一、列表页面工作。

列表页面工作其实比较好做,需要注意的是checkbox控件的name属性和value属性,以供后面向ajax传递所选的数据ID,我的代码是用<input type="checkbox" value="{$vo.id}" name="chkall">,完整代码如下:

<span class="l"> <a href="javascript:;" οnclick="app_delall(this)"  delall_url="{:url('student/delall')}" class="btn btn-danger radius"><i class="Hui-iconfont">&#xe6e2;</i> 批量删除</a> <a href="javascript:;" οnclick="app_edit(this)"  edit_url="{:url('student/add')}" class="btn btn-primary radius"><i class="Hui-iconfont">&#xe600;</i> 添加学生</a> <a href="javascript:;" οnclick="app_daoru(this)" daoru_url="{:url('admin/student/daoru')}" class="btn btn-primary radius"><i class="Hui-iconfont">&#xe645;</i> 导入EXCEL</a> <a href="javascript:;" οnclick="app_daochu(this)" daochu_url="{:url('admin/student/daochu')}" class="btn btn-primary radius"><i class="Hui-iconfont">&#xe644;</i> 导出EXCEL</a></span>

<form name='stulist' id="stulist">
    <table class="table table-border table-bordered table-bg table-hover table-sort table-responsive" >
      <thead>
      <tr class="text-c">
        <th width="25"><input type="checkbox" value="check" name="chkall" id="chkall" ></th>
        <th width="80">ID</th>
        <th  width="80">姓名</th>
        <th width="80">性别</th>
        <th width="80">民族</th>
        <th width="120">身份证号</th>
       
        <th width="120">操作</th>
      </tr>
      </thead>
      <tbody>
     {volist name='student' id="vo"}
      <tr class="text-c">
        <td><input type="checkbox" value="{$vo.id}" name="chkall"></td>
        <td>{$vo.id}</td>
        <td class="text-l"><u style="cursor:pointer" class="text-primary"  title="查看">{$vo.stuname}</u></td>
        <td>{$vo.sex|getSex}</td>
        <td>{$vo.Folk|getFolk}</td>
        <td>{$vo.IDNo}</td>
            
      </tr>
      {/volist}
      </tbody>
    </table>

   <div id="laypage"></div>

</form>

效果如下图

二、脚本代码

为了达到代码复用,我没有按网上说的把按钮放在form中,而是用在form外,这样点击按钮需要再写脚本响应按钮的click事件。app_delall函数代码如下:

function app_delall(obj) {

url = $(obj).attr('delall_url');
//alert(url);

     var chk_value =[];//定义一个数组 用于获取需要删除数据的ID   
     $('input[name="chkall"]:checked').each(function(){
     chk_value.push($(this).val());
      });
     //alert(chk_value);
    $.ajax({
        type:"POST",
        url:url,//url:"delall",
        data:{
            id:chk_value
        },
        success:function(e){
            if(e==1){
                alert('删除成功');
                location.href="index";
            }
            else{
                alert('删除失败');
                }
        }
    })

}

三、控制器代码

ajax把获取到的数据传递到控制器,由控制器执行删除操作。

public function delall() {

   $ids=input('post.');
   $id=$ids['id'];
   $model = $this->model ? $this->model : request()->controller();
   
   $len=count($id);
   $flag=true;
   //记录更新失败ID
        $error=[];
        
        for($i=0;$i<$len;$i++){
            
            $whereData[$i]= intval($id[$i]);
          
            $isRight = model($model)->where(array('id' => array('in', $ids)))->delete($id[$i]);
            
            if($isRight==0){
                //将更新失败的记录下来
                $error[]=$i;
                $flag=false;
            }
         
   if($isRight){
       return 1;
   }else{
       return 2;}
     }

至此全部结束。但在实现过程中确实走了不少弯路。现就所走弯路写出来,以避免大家再走。

1、脚本中获取url。

为了方便复用,我在页面上用了οnclick="app_delall(this)"  delall_url="{:url('student/delall')},来传递控制器地址,但由于脚本、控制器写好后,一直不能成功执行,不知道问题出在哪里,所以用alert(url);来查看传递的是否正确。由于控制器代码问题较大,一直不能成功执行,最后干脆把url直接写上,所以有了url:url,//url:"delall"。后来看这边没有问题,但在这里浪费不少时间。

2、控制器中接收数据

由于一直不能成功,怀疑是数据没有传递到控制器。查看日志,应该是传递成功的。

[ 2020-04-03T09:48:29+08:00 ] 127.0.0.1 127.0.0.1 POST /admin/student/delall
[ info ] www.csazs.com/admin/student/delall [运行时间:5.117293s][吞吐率:0.20req/s] [内存消耗:2,363.76kb] [文件加载:67]
[ info ] [ LANG ] D:\www\csaZB\thinkphp\lang\zh-cn.php
[ info ] [ ROUTE ] array (
  'type' => 'module',
  'module' => 
  array (
    0 => 'admin',
    1 => 'student',
    2 => 'delall',
  ),
)
[ info ] [ HEADER ] array (
  'x-requested-with' => 'XMLHttpRequest',
  'accept-language' => 'zh-cn',
  'referer' => 'http://www.csazs.com/admin/student/index.html',
  'accept' => '*/*',
  'content-type' => 'application/x-www-form-urlencoded; charset=UTF-8',
  'accept-encoding' => 'gzip, deflate',
  'user-agent' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)',
  'host' => 'www.csazs.com',
  'content-length' => '23',
  'connection' => 'Keep-Alive',
  'cache-control' => 'no-cache',
  'cookie' => 'thinkphp_show_page_trace=0|0; thinkphp_show_page_trace=0|0; __guid=115557120.3219521553895255000.1582160218890.2173; PHPSESSID=h3hkialued85b6mcmre9u45iv1',
)
[ info ] [ PARAM ] array (
  'id' => 
  array (
    0 => '27',
    1 => '26',
  ),
)
[ info ] [ SESSION ] INIT array (
  'id' => '',
  'var_session_id' => '',
  'prefix' => 'think',
  'type' => '',
  'auto_start' => true,
)
[ info ] [ RUN ] app\admin\controller\Student->delall[ D:\www\csaZB\application\admin\controller\Student.php ]
[ info ] [ LOG ] INIT File
[ error ] [8]Array to string conversion[D:\www\csaZB\application\admin\controller\Student.php:428]

后来又加了一句//alert(chk_value);证实了数据确实传递过去了。那么问题就只能是控制器了。开始对控制器代码逐一排查。

$ids=input('post.');接收需要删除的数据参数没有问题。调试代码看参数等也都没有问题,那么就是在执行删除操作中的错误了。查了很多,也试了很多,用save来进行修改status字段进行软删除,不行。网上都是用Db::table('test')->delete($id);来执行删除操作,而我一直都用的是model操作,不想用Db操作。于是不停的试,不停的找错误原因,最后才发现where条件写错了,所以一直不能执行,换成where(array('id' => array('in', $ids))),执行成功。

3、in操作符

一般情况下,SQL语句中in操作符的使用方式如下:

select * from `table1` where `id` in (1,2,3);

所以大家看到了,in操作符之后是一对小括号,把in的范围用括号括起来。


在ThinkPHP中,in操作的写法如下:
$where = array();
$where['id'] = array('in','1,2,3');
M('table1')->where($where)->select();

注意:

1、in之后不用把'1,2,3'用小括号再括起来,ThinkPHP在转换成SQL语句的过程中会自动添加小括号。

2、这里因为in的范围是数字,所以可以直接写'1,2,3'。如果是字符串,则需要使用数组的方式传递参数。如:
$list = array('a','b','c');
$where['type'] = array('in',$list);

综上所述,如果你的范围变量就是数组,那直接放到条件里面去就行。如果你的范围变量是字符串连起来的,那记得不用在外边加括号。(该部分内容来自洪哥笔记,ThinkPHP的where方法的in操作符说明http://www.splaybow.com/post/thinkphp-where-in-14263719.html

通过上面我走的这些弯路,希望大家引以为戒!以后有时间再研究一下saveAll,来实现软件删除功能!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值