menu

arrow_back Защо сортирана колекция (Laravel) показва грешен ред в компонент (Vue.js)?

by
1 vote
Господа. Тази вечер имам малко притеснение. И все пак, проблемът е следният.

Имаме колекция от атрибути, която е подредена по полето "позиция" в задната част на системата. На гърба всичко е наред, колекцията е сортирана правилно, по правилното поле.

Свързвам колекция с компонент на Vue, стартирам изброяване и то се извежда в ред по полето ID. От компонента пристига неправилно сортиран обект. Компонентът получава правилния, а изходът - грешния... Що за аматьорщина е това? И което е най-обидното, веднъж използвах такава логика с позиционирането, всичко беше правилно, но тук има някаква аномалия.

Код:
public function edit(int $attributeGroupId, AttributeGroupRepository $attributeGroupRepository)
{
$attributeGroup = $attributeGroupRepository->findAttributeGroupById($attributeGroupId);
$attributes = $attributeGroup->attributes->sortBy('position');

return view('admin.pages.attributes.attribute-groups.edit', compact('attributeGroup', 'attributes'));
}
Отстраняване на грешки:
Illuminate\Database\Eloquent\Collection {#1473 ▼
#items: array:3 [▼
0 => App\Entity\Attributes\Attribute {#1527 ▼
...
#attributes: array:7 [▼
"id" => 1
"attribute_group_id" => 1
"name" => "Размер экрана"
"value_type" => "text"
"sorting_type" => "alphanumeric"
"position" => 1
"display_in_filter" => 1
]
...
}
2 => App\Entity\Attributes\Attribute {#1525 ▼
...
#attributes: array:7 [▼
"id" => 4
"attribute_group_id" => 1
"name" => "Расширение экрана"
"value_type" => "text"
"sorting_type" => "numeric"
"position" => 2
"display_in_filter" => 1
]
...
}
1 => App\Entity\Attributes\Attribute {#1526 ▼
...
#attributes: array:7 [▼
"id" => 3
"attribute_group_id" => 1
"name" => "Цвет корпуса"
"value_type" => "color"
"sorting_type" => "position"
"position" => 3
"display_in_filter" => 1
]
...
}
]
}
Връзка:
<attributes-component  v-bind:attributes="{{ json_encode($attributes) }}"/>
И ето какво се получава в компонента:
attributes:Object
0:Object
attribute_group_id:1
display_in_filter:1
id:1
name:"Размер экрана"
position:1
properties:Array[7]
sorting_type:"alphanumeric"
value_type:"text"
1:Object
attribute_group_id:1
display_in_filter:1
id:3
name:"Цвет корпуса"
position:3
properties:Array[0]
sorting_type:"position"
value_type:"color"
2:Object
attribute_group_id:1
display_in_filter:1
id:4
name:"Расширение экрана"
position:2
properties:Array[0]
sorting_type:"numeric"
value_type:"text"
А самото претоварване, в името на яснотата, е тривиално:
<div v-for="attribute in attributes" :key="attribute.position" class="card">

4 Comments

и в раздела за мрежата, ако погледнете какво идва отзад?
Тъй като изходът е сортиран обект, а не масив
Ключовете на обектите в js автоматично се подреждат по азбучен ред, но не винаги, а в случай като вашия.

Колекция в php се превръща в обект чрез json_encode (което ще промени сортирането), а не в масив
Трябва да направите масив от колекцията и след това да го прехвърлите през json_encode, тогава няма да имате проблеми със сортирането.
Сергей Левченко Да, проблемът се оказа в ключовете. Забравих да ги възстановя...
$collection->toArray(); (Laravel изглежда има този метод)

1 Answer

by
0 votes
Ами... Както се казва, сутринта винаги е по-добре... Напълно ми убягна, че връзката ключ-стойност се запазва при сортиране на колекциите на Lara. И ако завършим израза с метода sortBy(), всичко е наред за php, но тъй като колекцията ни се втурва в ръцете на JS, тук идва трудната част.

Ето разширеният json, който влиза в компонента vue, и какво прави JS с него =)))

Json string:

"0":{
"id":1,
"attribute_group_id":1,
"name":"\u0420\u0430\u0437\u043c\u0435\u0440 \u044d\u043a\u0440\u0430\u043d\u0430",
"value_type":"text",
"sorting_type":"alphanumeric",
"position":1,
"display_in_filter":1,
"properties":[]
},
"2":{
"id":4,
"attribute_group_id":1,
"name":"\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430",
"value_type":"text",
"sorting_type":"numeric",
"position":2,
"display_in_filter":1,
"properties":[]
},
"1":{
"id":3,
"attribute_group_id":1,
"name":"\u0426\u0432\u0435\u0442 \u043a\u043e\u0440\u043f\u0443\u0441\u0430",
"value_type":"color",
"sorting_type":"position",
"position":3,
"display_in_filter":1,
"properties":[]
}
Обратите внимание на ключи объектов, 0, 2, 1 И вот что мы имеем на столе в JS:
"0":{
"id":1,
"attribute_group_id":1,
"name":"Размер экрана",
"value_type":"text",
"sorting_type":"alphanumeric",
"position":1,
"display_in_filter":1,
"properties":[]
},
"1":{
"id":3,
"attribute_group_id":1,
"name":"Цвет корпуса",
"value_type":"color",
"sorting_type":"position",
"position":3,
"display_in_filter":1,
"properties":{
}
},
"2":{
"id":4,
"attribute_group_id":1,
"name":"Расширение экрана",
"value_type":"text",
"sorting_type":"numeric",
"position":2,
"display_in_filter":1,
"properties":{
}
}
Ето го. Решението е адски банално:
$attributes = $attributeGroup->attributes->sortBy('position')->values()->all();
Благодарим на всички, които се опитват да помогнат! Както се казва, от време на време трябва да се чете документацията... Дори с един бърз поглед...