Laravel排序后的集合传递到JavaScript后顺序错乱问题
问题:Laravel集合排序后返回Ajax,JS接收时顺序错乱
在Laravel控制器中获取包含多种测量属性的产品集合,经unique()去重、sortBy()排序后返回给Ajax函数,但Ajax接收的对象顺序错乱。控制器用dd($lengths)查看时,集合按length字段有序;但在JavaScript中,lengths对象的排序状态未保留。
控制器代码
public function attributes(Request $request) { $diameter = $request->diameter; $length = $request->length; $rate = $request->rate; $type = $request->type; $products = Attributes::when($diameter, function($query, $diameter) { $query->where('diameter', $diameter); })->when($length, function($query, $length) { $query->where('length', $length); })->when($rate, function($query, $rate) { $query->where('rate', $rate); })->when($type, function($query, $type) { $query->where('type', $type); })->get(); $diameters = $products->unique('diameter')->sortBy('diameter'); $lengths = $products->unique('length')->sortBy('length'); $rates = $products->unique('rate')->sortBy('rate'); $types = $products->unique('type')->sortBy('type'); return ['diameters' => $diameters,'lengths' => $lengths,'rates' => $rates,'types' => $types]; }
控制器dd($lengths)输出
items: array:7 [ 9 => App\Models\Attribute ... "length" => "3.00"" ... 0 => ... "length" => "4.00"" 1 => ... "length" => "5.00"" .... ]
JavaScript接收结果
{diameters: Array(1), lengths: {…}, rates: Array(4), types: Array(1)} diameters : [{…}] lengths : 0 : {diameter: '2.25" I.D.', length: '4.00"', …} 4 : {diameter: '2.25" I.D.', length: '5.00"', …} 5 : {diameter: '2.25" I.D.', length: '6.00"', …} 6 : {diameter: '2.25" I.D.', length: '7.00"', …} 7 : {diameter: '2.25" I.D.', length: '8.00"', …} 8 : {diameter: '2.25" I.D.', length: '9.00"', …} 9 : {diameter: '2.25" I.D.', length: '3.00"', …} [[Prototype]] : Object rates : (4) [{…}, {…}, {…}, {…}] types : [{…}] [[Prototype]] : Object
原因&解决方法
原因
Laravel集合执行unique()和sortBy()后,仍保留原集合的非连续数字键(比如示例中的9、0、1)。当Laravel把集合转成JSON返回时,这些非连续数字键会被JS解析为对象属性,而JS对象的数字属性会被自动按升序排列,导致原本的排序失效。
解决
给每个处理后的集合调用values()方法,重置集合的键为连续索引(0、1、2...),这样转成JSON后就是JS数组,顺序会严格保留:
修改控制器中的集合处理代码:
$diameters = $products->unique('diameter')->sortBy('diameter')->values(); $lengths = $products->unique('length')->sortBy('length')->values(); $rates = $products->unique('rate')->sortBy('rate')->values(); $types = $products->unique('type')->sortBy('type')->values();
修改后,JS接收的lengths会变成有序数组,和控制器dd看到的顺序完全一致。
内容的提问来源于stack exchange,提问作者Casey
相关产品推荐
相关产品推荐

