Удалить запись JSON в VUE

У меня есть этот код

<script>
import './styling.scss'
export default {
  name: "app",
  data() {
    return {
      items: {books:[], authors:[]}
    };
  },

  created: function() {
    this.makeAjaxCall("books.json", "get").then(res => {
        this.items.books = res.books;
        return res;
    }),

    this.makeAjaxCall("authors.json", "get").then(res => {
        this.items.authors = res.authors;
        return res;
    })
  },

  },

  methods: {
    removeEntry:function(item) {
        this.$delete(this.items.books, item.name);
      },

    makeAjaxCall:function(url, methodType){
      var promiseObj = new Promise(function(resolve, reject){
          var xhr = new XMLHttpRequest();
          xhr.open(methodType, url, true);
          xhr.send();
          xhr.onreadystatechange = function(){
          if (xhr.readyState === 4){
            if (xhr.status === 200){
                //alert("xhr done ok");
                var response = xhr.responseText;
                var respJson = JSON.parse(response);
                resolve(respJson);
            } else {
                reject(xhr.status);
               //alert("xhr failed");
            }
          } else {
            //alert("xhr processing");
          }
      }
      //alert("request sent succesfully");
    });
    return promiseObj;
    }
  }
};
</script>
<template>
  <div id = "app">
    {{items.authors}}
    <table class = "booksTable">
      <thead>
        <tr>
          <th>Title</th>
          <th>Author</th>
          <th>Genre</th>
          <th>Image</th>
          <th>Availability</th>
          <th>Options</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for = "item in items.books" :key = "item.name">
              <td>{{item.name}}</td>
              <td>{{item.author}}</td>
              <td>{{item.genre}}</td>
              <td><img id = "imageBook" :src = "item.imageUrl"></td>
              <td v-if = "item.availability">Available</td>
              <td v-else>Unavailable</td>
              <td>
                <button class = "btn add">Add</button>
                <button class = "btn edit">Edit</button>
                <button class = "btn delete" v-on:click = "removeEntry(item)">Delete</button>
              </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

и мой JSON выглядит так

    "books": [
            {
                "name": "Lord of the rings",
                "author": 1,
                "year": 1937,
                "genre": 3,
                "imageUrl": "https://cdn.lifehack.org/wp-content/uploads/2015/03/9780618640157_custom-s6-c30.jpg",
                "availability": true
            },
            {
                "name": "To kill a mockingbird",
                "author": 2,
                "year": 1960,
                "genre": 1,
                "imageUrl": "https://cdn.lifehack.org/wp-content/uploads/2015/03/50-anniversary-cover1.jpg",
                "availability": true
            },
            {
                "name": "Harry Potter and the Philosopher’s Stone",
                "author": 3,
                "year": 2006,
                "genre": 3,
                "imageUrl": "https://cdn.lifehack.org/wp-content/uploads/2015/03/harry_potter_and_the_Sorcerers_stone_adult_usa.jpg",
                "availability": true
            }
}

Я хочу иметь возможность удалить запись из JSON, когда я нажимаю кнопку удаления. Не знаю, как это сделать. Необязательно: я хочу добавить или отредактировать записи. Было бы неплохо обновить таблицу после удаления / добавления / редактирования записи, но опять же, я понятия не имею, как это сделать. Есть идеи, как это сделать в vue?

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
0
1 854
1

Ответы 1

Обновите свой v-for, чтобы получить индекс, отправьте его в функцию removeEntry, когда вы нажмете кнопку, и обновите функцию removeEntry:

Шаблон:

<tr v-for = "(item, index) in items.books" :key = "item.name">
    ...
    <button class = "btn delete" v-on:click = "removeEntry(index)">Delete</button>
</tr>

Vue:

methods: {
    ...
    removeEntry:function(index) {
        this.$delete(this.items.books, index);
    }
}

Метод $delete работает с индексом Array + согласно документации https://vuejs.org/v2/api/#Vue-delete. Надеюсь, поможет.

РЕДАКТИРОВАТЬ:

Пожалуйста, попробуйте обновить функцию makeAjaxCall следующим образом:

makeAjaxCall:function(url, methodType, data){ // new argument `data`
    var promiseObj = new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest();
        xhr.open(methodType, url, true);
        // send `data` is exists
        if (data) {
            xhr.send(data);
        } else {
            xhr.send();
        }
        xhr.onreadystatechange = function(){
            if (xhr.readyState === 4){
                if (xhr.status === 200){
                    //alert("xhr done ok");
                    var response = xhr.responseText;
                    var respJson = JSON.parse(response);
                    resolve(respJson);
                } else {
                    reject(xhr.status);
                    //alert("xhr failed");
                }
            } else {
                //alert("xhr processing");
            }
        }
        //alert("request sent succesfully");
    });
    return promiseObj;
}

Также не забудьте вызвать в makeAjaxCall при удалении объекта из this.items.books и отправить обновленные данные, например JSON.stringify(this.items.books).

РЕДАКТИРОВАТЬ:

Пожалуйста, обновите метод removeEntry:

removeEntry:function(index) {
    this.$delete(this.items.books, index)
    this.makeAjaxCall('books.json', 'post', JSON.stringify(this.items.books))
}

@ IoanaMihăilescu, здесь v-for = "(item, index) in items.books"

Irina Potapova 14.12.2018 16:00

Я даже видел, что запись удаляется не из json, а только из таблицы.

Ioana Mihăilescu 14.12.2018 16:03

@ IoanaMihăilescu, он будет удален с this.items.books. Если вам нужно удалить его с вашего json, вы должны создать почтовый запрос через XMLHttpRequest.

Irina Potapova 14.12.2018 16:09

Ох, хорошо; Тогда я поищу что-нибудь в гугле. Спасибо!

Ioana Mihăilescu 14.12.2018 16:13

@ IoanaMihăilescu, пожалуйста, проверьте раздел EDIT. Думаю поможет.

Irina Potapova 14.12.2018 16:14

@ IoanaMihăilescu, можешь попробовать это?

Irina Potapova 14.12.2018 16:17

Он удаляет записи из таблицы, а не из json jsfiddle.net/ctwmz80p

Ioana Mihăilescu 14.12.2018 16:58

Извините, я не могу сейчас это проверить, @ IoanaMihăilescu

Irina Potapova 14.12.2018 16:58

@ IoanaMihăilescu, какой статус вы получили от XMLHttpRequest при удалении элемента? или у вас есть ошибки?

Irina Potapova 14.12.2018 21:45

App.vue: 69 POST локальный: 3000 / books.json 404 (не найдено) (анонимно) @ App.vue: 69 makeAjaxCall @ App.vue: 64 removeEntry @ App.vue: 60 щелкните @ App.vue? 6ff4: 1 n @ vue.runtime. esm.js: 2119 t._withTask.t._withTask @ vue.runtime.esm.js: 1904 App.vue: 81 Uncaught (в обещании) 404 a.onreadystatechange @ App.vue: 81 XMLHttpRequest.send (async) (анонимный ) @ App.vue: 69 makeAjaxCall @ App.vue: 64 removeEntry @ App.vue: 60 щелкните @ App.vue? 6ff4: 1 n @ vue.runtime.esm.js: 2119 t._withTask.t._withTask @ vue .runtime.esm.js: 1904 г.

Ioana Mihăilescu 17.12.2018 08:30

@ IoanaMihăilescu, похоже, что-то не так с путем к файлу "books.json"

Irina Potapova 17.12.2018 08:35

Да, но я не уверен, почему, потому что он там.

Ioana Mihăilescu 17.12.2018 09:36

Другие вопросы по теме