Обновление состояния массива vuex, когда один элемент имеет некоторые изменения - PullRequest
0 голосов
/ 03 июля 2018

В моем магазине Vuex есть массив с именем case.

Я хочу обновить массив новым содержимым при обновлении нескольких полей в существующем элементе в массиве.

Я думал, что смогу сделать что-то подобное в своей мутации, но не сработает и получит ошибку typeError: undefined is not an object (evaluating 'state.objects.find') -

EDIT_CASE (state, payload) {
    const item = state.objects.find(item => item.id === payload.recordId);
Object.assign(item, payload.case_status);

мой массив выглядит следующим образом:

[
    {
        "case_name": "Laptop not working",
        "case_status": "live",
        "case_summary": "This is some summary content",
        "createdBy": "zippy",
        "createdDate": "2018-06-21T15:20:22.932Z",
        "id": "-LFXvk9yY5c-O8yIdf8k"
    },
    {
        "case_name": "Something else",
        "case_status": "live",
        "case_summary": "This is some summary content",
        "createdBy": "zippy",
        "createdDate": "2018-06-21T15:20:22.932Z",
        "id": "-STVvk9yY5c-O3yiTy8k"
    }
]

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

По сути, у меня есть список, я делаю изменения в своем бэкэнде, теперь я хочу, чтобы этот список отражал изменения, внесенные мной при обновлении состояния дел, кто-нибудь может помочь?

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

JavaScript (не относится к Vue) не может обнаружить установку значения элемента Array напрямую по индексу arr[3] = 'stop'; Он также не может обнаружить добавление нового ключа или удаление существующего ключа из объекта. Вы должны определить начальное состояние магазина, например,

const store = new Vuex.Store({
  state: {
    objects: []
  },
  mutations: {
    EDIT_CASE (state, payload) {
      const index = state.objects.findIndex(item => item.id === payload.id);
      if (index !== -1) state.objects.splice(index, 1, payload);
    }
  }
})
0 голосов
/ 10 июня 2019

вам нужно обновить массив

const store = new Vuex.Store({
  state: {
    objects: [
      {id: 1, someProps: 'blablabla'},
      {id: 2, someProps: 'ololololo'}
   ]
  },
  mutations: {
    EDIT_CASE (state, data) {
      const index = state.objects.findIndex(item => item.id === data.id);
      state.objects[index].someProps = data.newPropsValue;

      //this is for vue reaction
      state.objects.push('dog-nail');
      state.objects.splice(-1,1);
  }
})
0 голосов
/ 03 июля 2018

В вашем примере нет проблем с массивом, потому что вы пытаетесь изменить свойство объекта - не элемент массива reference . Проблема в Object.assign(item, payload.case_status); - вы должны предоставить объект, а не просто поле. (Также вы сказали, что массив называется cases, но в примере есть objects, возможно, это тоже проблема);

Так что это должно работать:

EDIT_CASE (state, payload) {
    const item = state.objects.find(item => item.id === payload.recordId);
    Object.assign(item, payload);
}

Ошибка:

undefined не является объектом

Я думаю, это связано с Object.assign, потому что вы передаете ему поле, которое undefined , вероятно.

P.S. Есть небольшой пример, который поможет вам понять, когда возникает проблема с массивами и когда все работает нормально. Смотрите комментарии к коду:)

new Vue({
  el: "#app",
  data: {
    todos: [
      { text: "Learn JavaScript" },
      { text: "Learn Vue" },
      { text: "Play around in JSFiddle" },
      { text: "Build something awesome" }
    ]
  },
  methods: {
    // work because object property is reactive
  	changeItemProperty() {
    	this.todos[3].text = "changedItemProperty";
    },
    // same reason, properties are reactive
    changeItemWithAssign() {
    	Object.assign(this.todos[3], { text: "changedItemWithAssign" });
    },
    // does not work, can not track changes in array
    // also this will brake all attempts to change TEXT property in UI
    // because property is not reactive after this due to new object
    // try to changeItemProperty or  changeItemWithAssign - doses not work!
    // changeItem2 will fix it :)
    changeItem() {
    	this.todos[3] = { text: "changedItem" }
    },
    // works
    changeItem2() {
    	Vue.set(this.todos, 3, { text: "changedItem2" });
    }	
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
  <div v-for="todo in todos" :key="todo.text">
     {{todo.text}}
  </div>
  <button @click="changeItemProperty">changeItemProperty(works)</button>
  <button @click="changeItemWithAssign">changeItemWithAssign(works)</button>
  <button @click="changeItem">changeItem(does not work!)</button>
  <button @click="changeItem2">changeItem2(works)</button>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...