Laravel按排序返回数据

4

我在laravel中遇到了一个问题,无法返回json数据并将它们排序,它们只是随机出现。

我迄今为止所做的事情

  1. 我尝试通过从数据库中按id返回数据,并借助JavaScript排序,例如:

    result.sort(function(a,b) { return (a.id > b.id) ? 1 : ((b.id > a.id) ? -1 : 0); }); 结果是随机排序的

  2. 我向我的数据库添加了sort列,并尝试根据我提供的数字获取我的数据(结果是随机排序的)

  3. 我尝试在我的函数代码中添加->orderByRaw('set_specification.sort')来获取该顺序(结果是随机排序的)

逻辑

  1. 我选择一个set
  2. Set子项将按照我在其中提供数字的sort列顺序显示在blade上。

代码

控制器

public function selectset($id){
      $selectsets = DB::table('sets')
        ->where('sets.id', '=', $id)
        ->join('set_specification', 'sets.id', '=', 'set_specification.set_id')
        ->join('specifications', 'set_specification.spec_id', '=', 'specifications.id')
        ->orderByRaw('set_specification.sort')
        ->get();
      return response()->json($selectsets);
    }

JavaScript

$(document).ready(function() {
    $('select[name="selectset"]').on('change', function() {
      var id = $(this).val();
      if(id) {
      $.ajax({
        url: '{{ url('admin/selectset') }}/'+encodeURI(id),
        type: "GET",
        dataType: "json",
        success:function(result) {


          result.sort(function(a,b) {
            return (a.id > b.id) ? 1 : ((b.id > a.id) ? -1 : 0);
          });

          console.log(result);

//rest of code..
}

问题

即使在我的代码中通过ajax方式返回正确的数据(正如您在我的代码中所看到的),控制台也会返回正确结果,但在blade中它并未按照预期显示!

screenone

如果上面的图片无法工作,则请再次查看此处

问题

  1. 我该如何解决这个排序问题?

更新

我将AJAX代码更改为:

result.sort(function(a,b) {
  return (a.sort > b.sort) ? 1 : ((b.sort > a.sort) ? -1 : 0);
});

结果相同,截图如上。


你的数据库中 sort 列的类型是什么?我猜它不是整数。如果你按 id 排序,你需要指定表格,因为你正在连接多个不同的表格。 - fubar
不是 varchar :) - mafortis
1
转换为整数。 - fubar
我会尝试…… - mafortis
1
@Erubiel,我认为截图是按id排序的,而代码表明OP想按sort排序,这似乎是一个string,而不是一个int - fubar
显示剩余19条评论
2个回答

3
根据您在评论中提供的链接:https://www.codepile.net/pile/RlQoa6Dk,您正在将数据附加到ajax响应的html上。请记住,ajax是异步的,因此尽管您按顺序进行了ajax请求,但响应可能不会按照那个顺序发生。这就是为什么你总是得到随机的顺序...
您应该:
1. 进行第一个ajax调用 2. 对于响应中的每个元素,进行第二个ajax调用 3. 附加响应中每个元素的计算出的html 4. 一旦每个ajax调用终止,或者至少是多个ajax调用计算html,对现在拥有html的原始响应进行排序。 5. 对于响应中的每个元素,附加计算出的html 编辑 在进行ajax调用之前仅附加行起作用。
<script defer>
$(document).ready(function() {
    $('select[name="selectset"]').on('change', function() {
        var id = $(this).val();
        if(id) {
            $.ajax({
                url: '{{ url('admin/selectset') }}/'+encodeURI(id),
                type: "GET",
                dataType: "json",
                success:function(result) {
                    $('div#dataaamsg').empty();
                    $('div#dataaamsg').append('Use <kbd>CTRL</kbd> or <kbd>SHIFT</kbd> button to select multiple options');
                    result.sort(function(a,b) {
                        return (a.sort > b.sort) ? 1 : ((b.sort > a.sort) ? -1 : 0);
                    });

                    $.each(result, function(key1, value1) {

                        var vvvid = value1.id;

                        if(value1['type'] == 'textfield'){
                            var my_row = $('<div class="row mt-20 ccin">');
                            $('div#dataaa').append(my_row);
                        }else if(value1['type'] == 'textareafield'){
                            var my_row = $('<div class="row mt-20 ccin">');
                            $('div#dataaa').append(my_row);
                        }else{
                            var my_row = $('<div class="row mt-20">');
                            $('div#dataaa').append(my_row);
                        }

                        // second data
                        $.ajax({
                            url: '{{ url('admin/findsubspecification') }}/'+value1['id'],
                            type: "GET",
                            dataType: "json",
                            success:function(data) {
                                // Check result isnt empty
                                var helpers = '';
                                $.each(data, function(key, value) {
                                    helpers += '<option value="'+value.id+'">'+value.title+'</option>';
                                });

                                if(value1['type'] == 'textfield'){
                                    var my_html = '{{ Form::open() }}<input name="product_id" id="product_id" type="hidden" value="{{$product->id}}"><input name="specification_id" id="specification_id" type="hidden" value="'+vvvid+'"><div class="col-md-4">'+value1.title+'</div>';
                                    my_html += '<div class="col-md-6"><input id="text_dec" name="text_dec[]" placeholder="text field" class="text_dec form-control"></div>';
                                    my_html += '<div class="col-md-2"><button type="button" id="custmodalsavee" class="custmodalsavee btn btn-xs btn-success">Save</button>{{Form::close()}}</div>';
                                    my_row.html(my_html);
                                }else if(value1['type'] == 'textareafield'){
                                    var my_html = '{{ Form::open() }}<input name="product_id" id="product_id" type="hidden" value="{{$product->id}}"><input name="specification_id" id="specification_id" type="hidden" value="'+vvvid+'"><div class="col-md-4">'+value1.title+'</div>';
                                    my_html += '<div class="col-md-6"><textarea id="longtext_dec" name="longtext_dec[]" placeholder="text area field" class="longtext_dec form-control"></textarea></div>';
                                    my_html += '<div class="col-md-2"><button type="button" id="custmodalsavee" class="custmodalsavee btn btn-xs btn-success">Save</button>{{Form::close()}}</div>';
                                    my_row.html(my_html);
                                }else{
                                    var my_html = '{{ Form::open() }}<input name="product_id" id="product_id" type="hidden" value="{{$product->id}}"><div class="col-md-4">'+value1.title+'</div>';
                                    my_html += '<div class="col-md-6"><select class="subspecifications form-control tagsselector" id="subspecifications" name="subspecifications[]" multiple="multiple">'+helpers+'</select></div>';
                                    my_html += '<div class="col-md-2"><button type="button" id="sendspacsdatato" class="sendspacsdatato btn btn-xs btn-success">Save</button>{{Form::close()}}</div>';
                                    my_row.html(my_html);
                                }


                            }
                        });
                        // second data

                    });
                }
            });
        }else{
            $('div#dataaa').empty();
        }
    });
});
</script>

它停止在Blade中呈现我的数据(我只得到了空白)。 - mafortis
奇怪,控制台/开发工具中有任何错误日志吗? 这是您原始代码的问题,您理解问题了吗? - Erubiel
如果您不理解问题,可以打开devTools,进入网络选项卡并刷新页面,查看请求的执行过程……您可能会触发1、2、3、4、5等多个请求,但服务器响应的顺序可能是5、2、1、3、4或其他任何顺序,这就是所谓的异步处理……也正因为如此,您的HTML可能会被错误地添加。 - Erubiel
网络获取完整列表状态为200,但在控制台中出现TypeError: my_row未定义 - mafortis
尝试记录my_row,如果一些my_rows不为空,而另一些则改变了...可能存在另一个竞争条件... - Erubiel
显示剩余8条评论

0

在控制器中更新您的代码,如下所示

添加一个函数

public function cmp($a, $b)
{
    return strcmp($a['sort'], $b['sort']);
}

请将您的selectset函数更新为以下内容。
public function selectset($id){
$selectsets = DB::table('sets')
    ->where('sets.id', '=', $id)
    ->join('set_specification', 'sets.id', '=', 'set_specification.set_id')
    ->join('specifications', 'set_specification.spec_id', '=', 'specifications.id')
    ->orderByRaw('set_specification.sort')
    ->get();
usort($selectsets, array($this, "cmp"));
return response()->json($selectsets);
}

嗨,你确定usort是这样使用的吗?不应该加上$符号吗? - mafortis
好的,试一次。 - Harsh Virani
我得到了 SyntaxError: unexpected token: keyword 'function'[Learn More] - mafortis
这是一个完整的错误,以下是详细信息:public function cmp($a, $b) { return strcmp($a->sort, $b->sort); } - mafortis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接