Глобально загруженные данные в VueJs иногда равны нулю - PullRequest
0 голосов
/ 08 июля 2019

Я новичок в VueJ и в настоящее время пытаюсь загрузить некоторые данные только один раз и сделать их глобально доступными для всех компонентов Vue.Каков наилучший способ достичь этого?Я немного застрял, потому что глобальные переменные иногда кажутся нулевыми , и я не могу понять, почему.

В моем main.js я создаю три глобальные переменные экземпляра Vue:

let globalData = new Vue({
  data: {
    $serviceDiscoveryUrl: 'http://localhost:40000/api/v1',
    $serviceCollection: null,
    $clientConfiguration: null
  }
});
Vue.mixin({
  computed: {
    $serviceDiscoveryUrl: {
      get: function () { return globalData.$data.$serviceDiscoveryUrl },
      set: function (newUrl) { globalData.$data.$serviceDiscoveryUrl = newUrl; }
    },
    $serviceCollection: {
      get: function () { return globalData.$data.$serviceCollection },
      set: function (newCollection) { globalData.$data.$serviceCollection = newCollection; }
    },
    $clientConfiguration: {
      get: function () { return globalData.$data.$clientConfiguration },
      set: function (newConfiguration) { globalData.$data.$clientConfiguration = newConfiguration; }
    }
  }
})

и в свой компонент App.vue я загружаю все данные:

<script>
  export default {
    name: 'app',
    data: function () {
      return {
        isLoading: true,
        isError: false
      };
    },
    methods: {
      loadAllData: function () {
        this.$axios.get(this.$serviceDiscoveryUrl)
          .then(
            response => {
              this.$serviceCollection = response.data;

              let configurationService = this.$serviceCollection.services.find(obj => obj.key == "ProcessConfigurationService");

              this.$axios.get(configurationService.address + "/api/v1/clientConfiguration").then(
                response2 => {
                  this.$clientConfiguration = response2.data;
                }
              );
              this.isLoading = false;
            })
      }
    },
    created: function m() {
      this.loadAllData();
    }
  }
</script>

Но когда я пытаюсь получить доступ к $clientConfiguration, кажется, что null от временико времени, и я не могу понять, почему.Например, когда я пытаюсь построить навигационную боковую панель:

    beforeMount: function () {
      let $ = JQuery;
      let clients = [];
      if (this.$clientConfiguration === null)
        console.error("client config is <null>");

      $.each(this.$clientConfiguration, function (key, clientValue) {
        let processes = [];
        $.each(clientValue.processConfigurations, function (k, processValue) {
          processes.push(
            {
              name: processValue.name,
              url: '/process/' + processValue.id,
              icon: 'fal fa-project-diagram'
            });
        });

        clients.push(
          {
            name: clientValue.name,
            url: '/client/' + clientValue.id,
            icon: 'fal fa-building',
            children: processes
          });
      });

      this.nav.find(obj => obj.name == 'Processes').children = clients;

1 Ответ

1 голос
/ 08 июля 2019

Наиболее вероятной причиной является то, что null является только начальным значением. Загрузка данных выполняется асинхронно, поэтому вам нужно подождать, пока загрузка завершится, прежде чем пытаться создать какие-либо компоненты, основанные на этих данных.

У вас есть флаг isLoading, который, как я полагаю, является вашей попыткой дождаться завершения загрузки, прежде чем показывать какие-либо компоненты (возможно, через подходящий v-if). Однако в настоящее время он ожидает только первый запрос, а не второй. Итак, это:

this.$axios.get(configurationService.address + "/api/v1/clientConfiguration").then(
  response2 => {
    this.$clientConfiguration = response2.data;
  }
);
this.isLoading = false;

должно быть:

this.$axios.get(configurationService.address + "/api/v1/clientConfiguration").then(
  response2 => {
    this.$clientConfiguration = response2.data;
    this.isLoading = false;
  }
);

Если проблема не в этом начальном значении, вам нужно выяснить, что его устанавливает на null. Это должно быть очень просто, просто вставьте оператор debugger в свой установщик:

$clientConfiguration: {
  get: function () { return globalData.$data.$clientConfiguration },
  set: function (newConfiguration) {
    if (!newConfiguration) {
      debugger;
    }
    globalData.$data.$clientConfiguration = newConfiguration;
  }
}

Помимо проблемы с null, если вы используете Vue 2.6+, я бы посоветовал взглянуть на Vue.observable, который является более простым способом создания реактивного объекта, чем создание нового экземпляра Vue.

Лично я, вероятно, реализовал бы все это, поместив реактивный объект в Vue.prototype вместо использования глобального миксина. Это предполагает, что вам даже нужно, чтобы объект был реактивным, а если нет, то все это несколько сложнее, чем нужно.

...