Параметризованный геттер в Vuex - триггер Udpate - PullRequest
0 голосов
/ 03 сентября 2018

В моем магазине Vuex есть коллекция данных, скажем, 1000 записей. Есть метод получения с параметром getItem, который берет идентификатор и возвращает правильную запись.

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

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

Я все еще хочу вернуться к шаблону BehaviorSubject, который я часто использовал в Angular, но Vuex + rxJS кажется тяжелым для этого, верно?

Я чувствую, что мне нужно каким-то образом запустить триггер, чтобы геттер пересчитал.

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import VueResource from 'vue-resource'

Vue.use(VueResource);

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    numberOfPosts : -1,
    posts : {}, //dictionary keyed on slug
    postsLoaded : false,
  },
  getters : {
    postsLoaded : function(state){
      return state.postsLoaded;
    },
    totalPosts : function(state){
      return state.numberOfPosts;
    },
    post: function( state ){
      return function(slug){
        if( state.posts.hasOwnProperty( slug ) ){
          return state.posts.slug;
        }else{
          return null;
        }
      }
    }
  },
  mutations: {
    storePosts : function(state, payload){
      state.numberOfPosts = payload.length;
      for( var post of payload ){
        state.posts[ post.slug ] = post;
      }
      state.postsLoaded = true;
    }
  },
  actions: {
    fetchPosts(context) {
      return new Promise((resolve) => {
        Vue.http.get(' {url redacted} ').then((response) => {
          context.commit('storePosts', response.body);
          resolve();
        });
      });
    }
  }
})

Post.vue

 <template>
      <div class="post">
        <h1>This is a post page for {{ $route.params.slug }}</h1>
        <div v-if="!postsLoaded">LOADING</div>
        <div v-if="postNotFound">No matching post was found.</div>
        <div v-if="postsLoaded && !postNotFound" class="post-area">
          {{ this.postData.title.rendered }}
        </div>
      </div>
    </template>

<script>
import { mapGetters } from 'vuex'

export default {
  name: 'post',
  data : function(){
    return {
      loading : true,
      postNotFound : false,
      postData : null
    }
  },
  mounted : function(){
    this.postData = this.post( this.$route.params.slug );
    if ( this.postData == null ){
      this.postNotFound = true;
    }
  },
  computed : mapGetters([
    'postsLoaded',
    'post'
  ])
}
</script>

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

1 Ответ

0 голосов
/ 04 сентября 2018

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

  1. Доступ к хранилищу vuex осуществляется с помощью mapGetters в вычисляемом свойстве, которое вы уже сделали в Post.vue.
  2. Наблюдайте за отображенным свойством getters внутри вашего компонента, в вашем случае будет функция наблюдателя около postsLanded или post, независимо от того, что вы заботитесь об изменении его значения. Вам также может понадобиться свойство deep или immediate, отметьте API .
  3. Запускать мутации в хранилище vuex с помощью действий и, таким образом, изменять значение хранилища, которое получат ваши получатели.
  4. После изменения значения наблюдаемого свойства соответствующая функция наблюдения будет запущена со старым и новым значением, и вы сможете завершить свою логику там.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...