@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">
  • Вопрос задан
  • 73 просмотра
Пригласить эксперта
Ответы на вопрос 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();


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

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

Похожие вопросы