使用Laravel 4+从jQuery/ajax保存串行可排序数据


Saving serialised sortable data from jQuery/ajax using Laravel 4+

在找出将ajax可排序列表保存到数据库的最佳方法时遇到问题。我使用的是HTML5Portable和Laravel 4.2框架。我试图实现的基本最终结果是,用户可以点击并拖动列表项,然后对它们进行重新排序,这个新的顺序将保存在数据库中一个名为"顺序"的字段中,这样当他们稍后返回页面时,就会出现新的顺序。

我在页面上有一个章节列表,如下所示:

<ul class="sortable">
    @foreach ($chapters as $chapter)
      <li class="ui-state-default" data-order="{{ $chapter->order }}">{{ $chapter->title }}</li>
    @endforeach
</ul>

我可以使用HTML5Portable对这些数据进行拖放排序,然后序列化这些数据并通过ajax POST提交,每次列表重新排序时都会触发,如下所示:

$('.sortable').sortable().bind('sortupdate', function(e, ui) {
    var order = $('ul.sortable li').map(function(){ 
        return $(this).data("order");
    }).get();
    var uuid = "<?php echo$uuid; ?>";
    $.ajax({
        type: "POST",
        url: "api-ch-order",
        dataType: "json",
        data: {order: order, uuid: uuid},
        success: function(order){
          console.log(order)
        }
    });
});

我在/api ch订单上的控制器获取数据并保存新订单,如下所示:

if(Request::ajax()){
  $uuid = Input::get('uuid');
  $order = Input::get('order');
  $i = 1;
  foreach($order as $position) {
    $chapter = Chapter::where('book_uuid', $uuid)->where('order', $position)->first();
    $chapter->order = $i;
    $chapter->save();
    $i++;
  }
}

问题

我对这种方法的问题是,它在某些情况下不起作用,循环会导致问题。

例如

循环1:查找订单=2的章节,并将订单更改为1

循环2:找到顺序=1的章节,并将其更改为2

这里的问题是,在LOOP 2中,它正在查找LOOP 1的结果,并更新它。。。我想。。。这个问题让我很困惑。。。但我99%确信我的控制器中的foreach循环是问题所在,我不确定解决这个问题的最佳方法。

链接到此问题的资源:

  • 如何在Laravel 4中使用Jquery UI排序
  • 使用HTML5sortable为AJAX序列化数据

答案

正如r4xz所提到的,答案是使用ID作为常量。

例如

HTML

<ul class="sortable">
    @foreach ($chapters as $chapter)
      <li class="ui-state-default" data-id="{{ $chapter->id }}">{{ $chapter->title }}</li>
    @endforeach
</ul>

JS-

$('.sortable').sortable().bind('sortupdate', function(e, ui) {
    var id = $('ul.sortable li').map(function(){ 
        return $(this).data("id");
    }).get();
    var uuid = "<?php echo$uuid; ?>";
    $.ajax({
        type: "POST",
        url: "api-ch-order",
        dataType: "json",
        data: {id: id, uuid: uuid},
        success: function(order){
          console.log(id)
        }
    });
});

PHP控制器

if(Request::ajax()){
  $uuid = Input::get('uuid');
  $id = Input::get('id');
  $i = 1;
  foreach($id as $val) {
    $chapter = Chapter::where('id', $val)->first();
    $chapter->order = $i;
    $chapter->save();
    $i++;
  }
}

最常见的解决方案是保存仓位和实体id:

<li data-id="{{ $chapter->id }}" data-order="{{ $chapter->order }}">{{ $chapter->title }}</li>

然后在控制器中,您只需使用:

UPDATE chapter SET order = $order WHERE id = $id

这个问题非常有用,并给出了自己的答案!太棒了!谢谢

只是针对那些在我的情况下不使用相同结构的人。这就是我所做的:

public function myRouteFunction(Request $request)
    foreach($ids as $key => $id) {
        $update = DB::table('mybase')->where('id', $id)->update(['sort_order' => $key]);
    }
}

也许这可以帮助某人:)