Где я должен хранить JSON, полученный из запроса GET, чтобы у меня был доступ к нему в директиве v-for? - PullRequest
1 голос
/ 05 августа 2020

Я новичок в использовании API, поэтому, пожалуйста, простите меня, если это действительно тривиально.

Есть два запроса GET, которые я хочу использовать:

  • /workflow/search позволит мне получить полный список рабочих процессов вместе с их данными (т.е. идентификатором рабочего процесса).
  • /workflow/{workflowId} позволит мне получить конкретный c рабочий процесс с более подробной информацией.

Сейчас у меня есть importedWorkflows в моей функции данных, которая заполняется тем, что я получаю от вызова /workflow/search. Если я хочу узнать больше о рабочем процессе, я бы хотел позвонить по номеру /workflow/{workflowId}.

Однако это было действительно сложно, особенно потому, что я использую Jquery, чтобы получить JSON data.

$.getJSON(dataURL, function(data) {
      self.importedWorkflows = data.results;
    });

Поскольку все это асинхронно, мне действительно нужен доступ к информации, найденной с помощью /workflow/{workflowId}, когда она будет готова.

Это была моя попытка сделать это: у меня есть вычисляемый массив с именем importedWorkflowDefinitions, который обрабатывает все рабочие процессы, найденные с помощью /workflow/search, и вызывает вызов /workflow/{workflowId} для каждого рабочего процесса. Я сохраняю возвращенные JSON данные для каждого вызова в вычисленном массиве. Затем я использую метод под названием generateWorkflowById() для поиска рабочего процесса JSON в importedWorkflowDefinitions.

Однако ...

в моем приложении Vue , У меня есть таблица, созданная с помощью директивы v-for.

<tbody v-for="workflow in workflowsOnPage">
     <tr class="expandable-row" :id="workflow.workflowId">
          <td>{{ generateWorkflowById(workflow.workflowId).workflowName }}</td>
          <td>{{ workflow.workflowId }}</td>
          <td>{{ workflow.status }}</td>
          <td class="text-align-right">{{ workflow.startTime }}</td>
          <td class="text-align-right">{{ workflow.endTime }}</td>
          ...

Примечание: workflowsOnPage - это вычисленный массив JSON, который делит importedWorkflows.

Итак, по сути, произошло то, что таблица будет отображаться без значения generateWorkflowById(workflow.workflowId).workflowName, потому что первый вызов /workflow/search не был завершен. Кроме того, даже несмотря на то, что workflowDefinitions вычисляется и изменится после вызова /workflow/search, таблица уже завершила рендеринг и больше не будет запускать метод generateWorkflowById(..).

Есть ли способ отображать информацию, найденную с помощью вызова /workflow/{workflowId}, в таблицу без этой гонки, происходящей со всеми моими данными?

Кстати, я работаю с Netflix Conductor, поэтому, если есть более качественные вызовы API или другой способ иметь доступ ко всем деталям, относящимся к рабочему процессу, поэтому мне не нужно выполнять эти зависимые вызовы API, пожалуйста, дайте мне знать!

Спасибо!

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Здесь есть пара вещей ...

  1. Вычисленные свойства используются для возврата новых значений, основанных на реактивных свойствах. Они не должны выполнять какие-либо асинхронные функции.
  2. Вызов методов для визуализации частей вашего шаблона очень неэффективен и может привести к дальнейшим проблемам, таким как бесконечные циклы
  3. Смешивание Vue и jQuery? Просто скажите «нет» ?‍♂️

Здесь другой подход - получить все ваши данные в ловушке created вашего компонента и показать loading индикаторы для частей, которые все еще собираются

export default {
  data: () => ({
    importedWorkflows: []
  }),
  computed: {
    workflowsOnPage () {
      return .... // whatever you do to importedWorkflows to "divide" them
    }
  },
  async created () {
    const res = await fetch('/workflow/search')
    const workflows = (await res.json()).results

    // assign the new array values once all fetches are resolved
    this.importedWorkflows = await Promise.all(workflows.map(async workflow => {
      const res = await fetch(`/workflow/${workflow.workflowId}`)
      const details = await res.json() // assuming this is correct
      return {
        ...workflow,
        details
      }
    }))
  }
}
<p v-if="workflowsOnPage.length === 0">Loading...</p>

<!-- snip -->

<!-- this won't render until the "workflowsOnPage" array has elements -->
<tbody v-for="workflow in workflowsOnPage">
  <tr class="expandable-row" :id="workflow.workflowId">
    <td>{{ workflow.details.workflowName }}</td>
    <td>{{ workflow.workflowId }}</td>
    <td>{{ workflow.status }}</td>
    <td class="text-align-right">{{ workflow.startTime }}</td>
    <td class="text-align-right">{{ workflow.endTime }}</td>
    <!-- etc -->
  </tr>
</tbody>

Обратите внимание, что я загрузил дополнительные сведения из /workflow/{workflowId} в свойство details каждого объекта workflow, возвращенного /workflow/search.

0 голосов
/ 05 августа 2020

Краткий ответ: используйте хранилище vuex, зарегистрируйте действие, которое выполнит запрос на получение и создаст мутацию, которая будет сохранять ответ запроса на переменную состояния внутри переменной хранилища, а затем извлекать переменную хранилища с помощью вычисленного и использовать это в ваш шаблон

...