Feathersjs-Vuex: как обновить состояние vuex из запроса sql

Чтобы получить представление об этом вопросе, я рекомендую прочитать ветку ниже:

Я покажу контексты моего вопроса на стороне сервера и внешнего интерфейса:

Бэкэнд

  • сервер flesjs;
  • на сервере есть 3 сервиса: пользователи, оценки и студенты;
  • используемый адаптер базы данных - sequelize для базы данных postgresql.

Внешний интерфейс

  1. Сборка рендеринга на стороне сервера в nuxt с vuetify;
  2. Feathers-vuex для управления состояниями.
  3. запрос страницы '/ profile' (интерфейс) для аутентифицированного пользователя ('/ users' в бэкэнде)
  4. страница '/ grades' (интерфейс) запрашивает запрос для всех оценок, принадлежащих аутентифицированному пользователю ('/ grades' в бэкэнде)
  5. страница '/ student' (интерфейс) запрашивает запрос для всех учащихся, принадлежащих к любым оценкам аутентифицированного пользователя ('/ студенты' в бэкэнде)

Итак, мой конкретный вопрос касается пункта 5 контекста внешнего интерфейса. С помощью следующего кода я могу получить всех учащихся, принадлежащих к любым оценкам прошедшего аутентификацию пользователя, но вычисленное свойство students возвращает пустой массив:

<script>
import { mapState, mapGetters, mapActions } from 'vuex'

export default {
  computed: {
    ...mapState('students', { areStudentsLoading: 'isFindPending' }),
    ...mapGetters('students', { findStudentsInStore: 'find' }),
    query () {
      return {
        query: {
          $sort: {
            first_name: 1,
            last_name: 1
          },
          $select: ['first_name', 'last_name'],
          include: [{
            model: 'grades',
            where: {
              userUuid: this.$store.state.auth.user.uuid
            }
          }]
        }
      }
    },
    computed () {
      return this.findStudentsInStore(this.query).data
    }
  },
  created () {
    this.findStudents(this.query)
  },
  methods: {
    ...mapActions('students', { findStudents: 'find' })
  }
}
</script>

Итак, findStudents - это запрос AJAX, и в ветке комментариев кто-то ответит:

Axios (и AJAX в целом) является асинхронным, что означает, что операция начинается отдельно от обычного синхронного потока кода. После ее начала выполнение программы немедленно возобновляется, часто до завершения асинхронной операции. Пока вы входите в консоль, нет гарантии, что это асинхронное обещание еще не выполнено.

Кроме того, нет необходимости в этом геттере, который вы можете рассматривать как вычисляемый, который ничего не вычисляет.

Итак, я протестировал следующий код, в котором я заменил вычисляемое свойство student на данные студента, и он сработал:

<script>
import { mapActions } from 'vuex'

export default {
  computed: {
    query () {
      return {
        query: {
          $sort: {
            first_name: 1,
            last_name: 1
          },
          $select: ['first_name', 'last_name'],
          include: [{
            model: 'grades',
            where: {
              userUuid: this.$store.state.auth.user.uuid
            }
          }]
        }
      }
    }
  },
  data () {
    return { students: [] }
  },
  created () {
    this.findStudents(this.query).then((response) => {
      this.students = response.data
    })
  },
  methods: {
    ...mapActions('students', { findStudents: 'find' })
  }
}
</script>

Итак, мой вопрос: есть ли способ обновить состояние учеников ОС в магазине, или я должен полагаться на последний подход?


person gcrav    schedule 27.04.2021    source источник


Ответы (1)


Имея некоторый опыт программирования, я нашел решение. Я надеюсь, что это поможет кому-то с подобными проблемами.

  1. Во-первых, источником проблемы была служебная ловушка, которая анализирует запрос загрузки.
  2. Во-вторых, я заменил ...mapGetters('students', { findStudents: 'find' }).

Backend: исправление служебного хука с нетерпеливой загрузкой

Я заметил, что производительность при синтаксическом анализе важна. Я делал for loop в каждом элементе include paramm, и это задерживало ответ.

Итак, я оптимизировал ловушку нетерпеливой загрузки на сервере:

src / eager_loading.js

const _ = require('lodash');

const eager_loading = function() {
  return async function (context) {
    if (context.params.query && context.params.query.include) {
      console.log(context.params.query);
      context.params.sequelize = {
        include: _.map(context.params.query.include, function(query) {
          console.log (query);
          return _.update(query, 'model', function(m) {
            return context.app.service(m).Model;
          });
        })
      };
      delete context.params.query.include;
    }
    return context;
  }
};

module.exports = eager_loading;

src / app.hooks.js

// Application hooks that run for every service
const eager_loading = require('./eager_loading');

module.exports = {
  before: {
    all: [],
    find: [
      eager_loading()
    ],
    get: [],
  },
  // etc...

Фронтенд: замените find getter на получение списка

Время ответа на стороне клиента было быстрее. У меня нет числовых значений измерения, но это было визуально заметно на Vue.devtools, а ответ был обновлен в геттерах vuex.

страницы / студенты / index.vue

<script>
import { mapState, mapGetters, mapActions } from 'vuex'

export default {
  filters: {
    complete_name (student) {
      return `${student.first_name} ${student.last_name}`
    },
    grade (student) {
      return student['grade.grade']
    }
  },
  computed: {
    ...mapState('students', { areStudentsLoading: 'isFindPending' }),
    ...mapGetters('students', { listStudentsInStore: 'list' }),
    query () {
      return {
        query: {
          $sort: {
            first_name: 1,
            last_name: 1
          },
          $select: ['first_name', 'last_name', 'uuid'],
          include: [{
            model: 'grades',
            attributes: ['grade'],
            where: {
              userUuid: this.$store.state.auth.user.uuid
            }
          }]
        }
      }
    },
    students () {
      return this.listStudentsInStore
    },
    loading () {
      return this.areStudentsLoading
    }
  },
  created () {
    this.findStudents(this.query)
  },
  methods: {
    ...mapActions('students', { findStudents: 'find' })
  }
}
</script>

person gcrav    schedule 01.05.2021