Как сопоставить данные, организованные в виде массива, с настройками конфигурации (связанные с перетаскиванием Vue)

У меня есть особая проблема, связанная с vue draggable, которую также можно рассматривать как общий вопрос, связанный со структурой данных (массивом). (пример: vue-draggable-test)

Vue draggable используется для переупорядочения элементов массива, поэтому вам придется работать с массивом.

В моем приложении вы можете добавлять/удалять элементы в каждую группу и изменять порядок групп.

В настоящее время моя структура данных представляет собой массив, состоящий из массивов элементов (объектов), каждый массив принадлежит определенной группе.

dataGroups: [
    [ 
        {
            groupName: 'firstGroup',
            textContent: 'Hello this is an item for first group.'
        },
        {
            groupName: 'firstGroup',
            textContent: 'Another item for first group'
        }
    ], 
]

Каждая группа имеет определенные настройки, например, максимальное количество элементов (или numElements), хранящихся в отдельном объекте конфигурации:

 datagroupsConfig: [
     {
      name: 'firstGroup',
       numElements: 3
    },
   {
      name: 'otherGroup',
       numElements: 1
    },

Проблема в том, что при зацикливании групп и элементов, как я могу отслеживать, к какой группе он принадлежит? (так как это массив)?

Раньше (до использования vue draggable) я использовал объект:

{
  mygroup: [ {},{},]
}

который может быть сопоставлен с объектом конфигурации.

Но если группы и элементы организованы в массивы, нет указания, к какой группе они принадлежат (за исключением того, что любые существующие элементы имеют свойство groupName, которое можно проверить).

Первоначально группы данных могут быть пустыми, поэтому они не имеют идентификации. Количество исходных групп данных должно определяться объектом конфигурации.

Я сделал пример, чтобы показать эту проблему: перетаскиваемый тест

Вот просто чтобы продемонстрировать, как это зациклено (из моего примера):

<draggable v-model="form.dataGroups" 
    @start="drag=true" 
    @end="drag=false"  
    ghost-class="ghost" 
    class="row"
>
    <div v-for="(boxGroup, idx) in form.dataGroups" 
        :key="`group_${idx}`" 
        class="drag-element flex-center"
        style="display:flex"
    >
        <!-- add item to the current datagroup - but check the config if it is allowed -->
        <a v-if="doSomeCheck"   
            @click="openAddItemWindow(idx)" 
            class="btn btn2"  
            v-cloak>Add new item
        </a>

        <div v-for="(item, idx) in boxGroup" 
            :key="`item_${idx}`"
            class="boxgroup-item"
        >
            <p class="font-sm" >{{item.textContent }}</p>
            <p>{{boxGroup.textContent}}</p>
        </div>
    </div>

</draggable>

Итак, как я могу изменить структуру данных или внести какие-либо другие изменения, чтобы решить эту проблему, сохраняя при этом функции перетаскивания/переупорядочивания. Есть ли какие-то традиционные решения, которые я пропустил?


person Galivan    schedule 16.02.2021    source источник


Ответы (2)


Массивы Javascript — это объекты, поэтому вы можете определить свойства для каждой из ваших групп данных.

const datagroup1 = [];
datagroup1.numElements = 3;

const datagroup2 = [];
datagroup2.numElements = 4;

const dataGroups: [
    datagroup1,
    datagroup2, 
];
person eldo    schedule 18.02.2021
comment
Спасибо за предложение, я использовал вложенную структуру, которая, кажется, работает, я не тестировал добавление свойств объекта в массив, может быть, это не так обычно? Я должен попробовать это все же. - person Galivan; 20.02.2021
comment
Я думаю, это просто то, как вы на это смотрите. Если это объект с итерируемым свойством или сам объект является итерируемым (как и сам массив), это не кажется нетрадиционным. - person eldo; 20.02.2021

Я понял, что могу создать более вложенную структуру, используя объект с двумя свойствами: properties (со свойствами конфигурации) и datagroup (массив элементов).

Я изменил рабочий пример: рабочий пример.

dataGroups : [
    { 
        properties: { 
            name:"firstGroup",
            numElements:3
        },
        dataGroup: [
          {
            groupName:"firstGroup",
            textContent:"Hello this is an item for first group."
          },
          {
            groupName:"firstGroup",
            textContent:"Another item for first group"
          }
        ]
    },
    { 
      properties: { 
           name:"secondGroup",
           numElements:1
      },
      dataGroup: [
          {
            groupName:"secondGroup",
            textContent:"This is an item for second group"
          }
      ]
   }
]

И это, кажется, способ решить эту проблему.

person Galivan    schedule 19.02.2021