You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中jQuery UI Sortable使用UUID时排序异常的解决方法

解决jQuery UI Sortable使用UUID作为标识时排序失效的问题

我之前也碰到过一模一样的问题!核心原因是jQuery UI Sortable的serialize()方法默认会把元素ID按前缀-ID的格式拆分,UUID自带的连字符会被当成前缀和ID的分隔符,导致拆分出来的ID只有UUID的第一段(比如b20s0b82),后端自然找不到对应的模型,排序功能就失效了。

下面给你两种可靠的解决办法,推荐第一种,更直观灵活:

方法一:手动构造排序数据(推荐)

这种方法避开了serialize()的默认规则,改用data-*属性存储UUID,然后手动收集排序后的UUID数组,完全不会有分隔符冲突的问题。

1. 修改视图文件(index.blade.php)

把原来的id="item-{{$blogs->uuid}}"改成用data-uuid属性存储UUID,id可以保留或者去掉(这里保留也不影响):

<tbody id="sortable">
    @foreach($data['blogs'] as $blogs)
    <tr id="item-{{$blogs->uuid}}" data-uuid="{{$blogs->uuid}}">
        <td>{{$loop->iteration}}</td>
        <td><img width="100" src="/images/blogs/{{$blogs->blogs_file}}" alt=""></td>
        <td class="sortable">{{$blogs->blogs_title}}</td>
        <td>{{Illuminate\Support\Str::limit($blogs->blogs_content, 15)}}</td>
        <td align="center" width="20">
            <a href="#"><i class="fa fa-pencil-square"></i></a>
        </td>
        <td align="center" width="20">
            <a href="javascript:void(0)"><i id="{{$blogs->uuid}}" class="fa fa-trash-o"></i></a>
        </td>
    </tr>
    @endforeach
</tbody>

2. 修改jQuery代码

去掉serialize(),手动遍历排序后的<tr>,收集data-uuid的值,构造请求数据:

$(function () {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
    $('#sortable').sortable({
        revert: true,
        handle: ".sortable",
        stop: function (event, ui) {
            // 手动收集排序后的UUID数组
            var sortedItems = $('#sortable tr').map(function() {
                return $(this).data('uuid');
            }).get();
            
            $.ajax({
                type: "POST",
                data: { items: sortedItems }, // 传递排序后的UUID数组
                url: "{{route('blogs.Sortable')}}",
                success: function (msg) {
                    if (msg) {
                        alertify.success('İşlem Başarılı');
                    } else {
                        alertify.error('İşlem Başarısız');
                    }
                }
            });
        }
    });
    $('#sortable').disableSelection();
});

3. 修改BlogController代码

现在接收的是items数组,根据UUID查找模型并更新排序字段:

use Illuminate\Http\Request;

public function sortable(Request $request)
{
    foreach ($request->items as $key => $uuid) {
        // 通过UUID查找对应博客
        $blogs = Blogs::where('uuid', $uuid)->first();
        if ($blogs) {
            $blogs->blogs_must = intval($key);
            $blogs->save();
        }
    }
    // 返回JSON格式的响应更规范
    return response()->json(true);
}

方法二:修改serialize的正则表达式

如果想继续使用serialize()方法,可以自定义它的拆分规则,让它正确识别带连字符的UUID。

1. 视图文件无需修改

保持原来的<tr id="item-{{$blogs->uuid}}">即可。

2. 修改jQuery代码

在调用serialize()时,指定expression选项,用正则匹配出完整的UUID:

stop: function (event, ui) {
    // 自定义正则,匹配item-前缀后的所有内容(包括UUID里的连字符)
    var data = $(this).sortable('serialize', {
        expression: /^item-(.+)$/
    });
    $.ajax({
        type: "POST",
        data: data,
        url: "{{route('blogs.Sortable')}}",
        success: function (msg) {
            if (msg) {
                alertify.success('İşlem Başarılı');
            } else {
                alertify.error('İşlem Başarısız');
            }
        }
    });
}

这里的正则/^item-(.+)$/会贪婪匹配item-之后的所有字符,包括UUID里的连字符,这样就能得到完整的UUID了。

3. 修改BlogController代码

和方法一类似,改成通过UUID查找模型:

use Illuminate\Http\Request;

public function sortable(Request $request)
{
    foreach ($request->item as $key => $uuid) {
        $blogs = Blogs::where('uuid', $uuid)->first();
        if ($blogs) {
            $blogs->blogs_must = intval($key);
            $blogs->save();
        }
    }
    return response()->json(true);
}

两种方法都能解决问题,个人更推荐第一种,因为它不依赖serialize()的规则,后续如果UUID格式变化也不容易出问题。

内容的提问来源于stack exchange,提问作者BoraN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 19:37:36