@Glebkiselev11
Vue.js разработчик

Как правильно описать логику преобразования данных к нужному виду в vuex actions?

Столкнулся с проблемой, что у меня actions стали слишком сильно раздуты в объеме логики, как правильней это все разделить:

convertReceivedDataAndHeaders({commit}, response) {

      const {
        head_info: headersInfo, // Вытаскиваем настройки таблицы (пагинация, количество колонок и тд)
        fields: headers, // Вытаскиваем название колонок, тип колонок
        rows : data // Вытаскиваем данные таблицы
      } = response
      
      commit('setHeadersInfo', headersInfo) // Сразу отдаем данные из заголовков
      
      let filteredHeadersArray = []
      let howManyGridColumnsToShow = 0 // Число колонок которые должны показываться в гриде (нужно для css grid)
      let index = 0
      // Обрабатываем заголовки, именно проходимся по англ названиям, как первичным ключам        
      for (let element in headers) {         
        filteredHeadersArray[index] = {
          'FIELD_NAME' : element.toUpperCase(), // Англ название (в snake_case) приводим к верхнему регистру
          'FIELD_CAPTION' : headers[element]['caption'], // Русское название
          'TYPE' : headers[element]['field_type'], // Номер типа данных, если 1 то это Number, 2 - String
          'IS_PK' : headers[element]['is_pk'], // Если 1, то эта колонка является первичным ключом, если 0, то нет
          'IS_VISIBLE' : headers[element]['is_visible'], // Если 1 то отображаем в гриде эту колонку, если 0, то нет
        }
        index++

        // Прибавляем считчик колонок которые нужно показывать
        headers[element]['is_visible'] == 1 ? howManyGridColumnsToShow++ : 0
      }

      // Сортируем полученный массив заголовков таким образом, чтобы первой колонкой всегда был IS_PK
      filteredHeadersArray = filteredHeadersArray.sort((a, b) => {
        return b['IS_PK'] - a['IS_PK']
      })

      
      let filteredDataArray = []
      // Формируем данные таблицы, отталкиваясь от вычесленных заголовков таблицы
      for (let i = 0; i < filteredHeadersArray.length; i++) {
        // Получаем тип данных для столбца
        const typeInColum = filteredHeadersArray[i]['TYPE'] == 1 ? Number : String
        // Получаем информацию, нужно ли показывать это поле или нет
        const visible = filteredHeadersArray[i]['IS_VISIBLE']
        // На каждой итерации получаем массив значений одного столбца таблицы (по вертекали)
        let dataArray = data[filteredHeadersArray[i]['FIELD_NAME']]
        
        // Если в данных ничего нету, то заполняем ее пустыми данными: первому элементу (он у нас всегда id) даем -1
        // (чтобы по клику на это поля он вызывал создание нового поля, а не редактирование), а всем остальным пустое значение
        if (!dataArray) {
          dataArray = i === 0 ? [-1] : [0]
        }

        // Раскидываем по массивам значения, по сути мы из "вертикальных массивов" делаем "горизонтальные"
        for (let x = 0; x < dataArray.length; x++) {
          // Сразу как закидываем преобразовываем к нужному типу
          if (i === 0) {
            // На первой итерации верхнего цикла мы создаем мыссивы (первую колонку)
            filteredDataArray.push([ { value : typeInColum(dataArray[x]), visible } ])
          } else {
            // На второй итерации верхнего цикла мы уже добавляем в эти колонки значения
            filteredDataArray[x].push( { value : typeInColum(dataArray[x]), visible})
          }
        }
      }

      //  Дополнительная обработка на цвет текста и цвет бэкраунда
      for (let i = 0; i < filteredHeadersArray.length; i++) {
        const fieldName = filteredHeadersArray[i]['FIELD_NAME']
        // Находим тот нужный нам объект где хранятся данные о цвете 
        const colorType = fieldName === 'FONT_COLOR' ? 'FC' : fieldName === 'BG_COLOR' ? 'BC' : null
        
        if (colorType) {
          const dataArray = data[fieldName] // На каждой итерации получаем массив значений одного столбца таблицы

          for (let c = 0; c < dataArray.length; c++) {
            let num = parseInt(dataArray[c]) // Преобразовываем сначала в число
            let hex = num.toString(16) // А потом в формат HEX

            filteredDataArray[c].forEach((item) => {
              if (dataArray[c] == -1) return // Прерываем цикл, если значение по умолчанию
              return item[colorType] = '#' + (hex.length < 2 ? hex + '00000' : 
                                              hex.length < 3 ? hex + '0000' :
                                              hex.length < 4 ? hex + '000' :
                                              hex.length < 5 ? hex + '00' :
                                              hex.length < 6 ? hex + '0' : hex)
            })
          }
        }
      }
      
      commit('setHeadersAndData', { // Передаем обработанные данные в стейт
        gridHeaders : filteredHeadersArray, 
        gridData : filteredDataArray,
        howManyGridColumnsToShow
      })

    }


Это все один dispatch, со временем он раздулся до такого размера, что очень не круто.

Как правильней описывать такую большую логику преобразования данных, наделать кучу dispatch'ей или вообще вынести эту логику в другой отдельный файл?
  • Вопрос задан
  • 59 просмотров
Решения вопроса 1
Kozack
@Kozack Куратор тега Vue.js
Thinking about a11y
Читайте про методологию рефакторинга раздутых функций — https://refactoring.guru/ru/smells/long-method
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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