@oreym

Почему отсортированная коллекция (Laravel) неверно отображает порядок в компоненте (Vue.js)?

Господа. Что-то я под вечер нормально так завис. Вообщем суть проблемы.

Имеем коллекцию атрибутов, которая на беке сортируется по полю 'position'. На беке все отлично, коллекция сортируется правильно, по нужному полю.

Биндю коллекцию в компонент 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">
  • Вопрос задан
  • 71 просмотр
Пригласить эксперта
Ответы на вопрос 1
@oreym Автор вопроса
Ну что ж... Как говорится, утро вечера мудренее... Совсем вылетело из головы, что при сортировке коллекций лары сохраняется связь ключ-значение. И если мы заканчиваем выражение методом 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();


Всем спасибо, что пытался помочь! Как говорится, надо переодически почитывать документашечку... Зоть быстрым взглядом...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы