Vuetify datatable reload при выполнении операций CRUD - PullRequest
0 голосов
/ 13 января 2020

У меня есть простой набор данных vuetify, который выполняет операции CRUD. Я использую топор ios и базу данных mon go. Когда я добавляю новый элемент, информация корректно отображается на стороне клиента и публикуется в базе данных mon go. Однако Я не могу получить доступ к обновленной информации базы данных mon go, в частности к идентификатору, который mon go создал , если я не перезагружу веб-страницу. Я новичок в Vue, наберитесь терпения. Упрощенная версия задачи:

 axios
   .post('http://localhost:5000/dessert', {
   name: this.editedItem.name
 })

 console.log(this.editedItem.name) // I CAN ACCES WITHOUT PROBLEM
 console.log(this.editedItem._id) // I NEED TO RELOAD THE WEBPAGE IN ORDER TO ACCES THIS ELEMENT. THE ID THAT MONGO CREATED.

Vue файл :

<template>
  <v-data-table
    :headers="headers"
    :items="desserts"
    sort-by="calories"
    class="elevation-1"
  >
    <template v-slot:top>
      <v-toolbar flat color="white">
        <v-toolbar-title>My CRUD</v-toolbar-title>
        <v-divider
          class="mx-4"
          inset
          vertical
        ></v-divider>
        <v-spacer></v-spacer>
        <v-dialog v-model="dialog" max-width="500px">
          <template v-slot:activator="{ on }">
            <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
          </template>
          <v-card>
            <v-card-title>
              <span class="headline">{{ formTitle }}</span>
            </v-card-title>

            <v-card-text>
              <v-container>
                <v-row>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.name" label="Dessert name"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.calories" label="Calories"></v-text-field>
                  </v-col>
                </v-row>
              </v-container>
            </v-card-text>

            <v-card-actions>
              <v-spacer></v-spacer>
              <v-btn color="blue darken-1" text @click="close">Cancel</v-btn>
              <v-btn color="blue darken-1" text @click="save">Save</v-btn>
            </v-card-actions>

          </v-card>
        </v-dialog>
      </v-toolbar>
    </template>

    <template v-slot:item.action="{ item }">
      <v-icon
        small
        class="mr-2"
        @click="editItem(item)"
      >
        edit
      </v-icon>
      <v-icon
        small
        @click="deleteItem(item)"
      >
        delete
      </v-icon>
    </template>

    <template v-slot:no-data>
      <v-btn color="primary" @click="initialize">Reset</v-btn>
    </template>
  </v-data-table>
</template>

<script>
import axios from 'axios'

  export default {
    data: () => ({
      dialog: false,
      headers: [
        {
          text: 'Dessert (100g serving)',
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Actions', value: 'action', sortable: false },
      ],
      desserts: [],
      editedIndex: -1,
      editedItem: {
        name: '',
        calories: 0,
      },
      defaultItem: {
        name: '',
        calories: 0,
      },
    }),
    mounted() {
       this.fetchItems()
    },

    computed: {
      formTitle () {
        return this.editedIndex === -1 ? 'New Item' : 'Edit Item'
      },
    },
    watch: {
      dialog (val) {
        val || this.close()
      },
    },
    created () {
      this.initialize()
    },

    methods: {
      fetchItems(){
      axios
        .get('http://localhost:5000/dessert')
        .then(response => (this.desserts = response.data.data))
        },

      editItem (item) {
        this.editedIndex = this.desserts.indexOf(item)
        this.editedItem = Object.assign({}, item)
        this.editedID = this.editedItem._id
        this.name = this.editedItem.name
        this.calories = this.editedItem.calories
        this.dialog = true
      },

      deleteItem (item) {
        const index = this.desserts.indexOf(item)
        this.deletedItem = Object.assign({}, item)
        console.log(this.deletedItem)
        this.deletedID = this.deletedItem._id
        console.log(this.deletedID)
        if (confirm("Do you really want to delete?")) {
          axios.delete(`http://localhost:5000/dessert/${this.deletedID}`);
          this.desserts.splice(index, 1);
        }
      },

      close () {
        this.dialog = false
        setTimeout(() => {
          this.editedItem = Object.assign({}, this.defaultItem)
          this.editedIndex = -1
        }, 300)
      },
      save () { // Edit Item
        if (this.editedIndex > -1) {
          Object.assign(this.desserts[this.editedIndex], this.editedItem)
          axios.delete(`http://localhost:5000/dessert/${this.editedItem._id}`)
          axios
            .post('http://localhost:5000/dessert', {
            name: this.editedItem.name,
            calories: this.editedItem.calories
            })

          // New Item
        } else {
          this.desserts.push(this.editedItem)

          axios.post('http://localhost:5000/dessert', {
          name: this.editedItem.name,
          calories: this.editedItem.calories
          })
        }

        this.close()
      },
    },
  }
</script>

Python файл :

from flask import Flask
from flask import jsonify
from flask import request
from flask_pymongo import PyMongo
from flask_cors import CORS
from bson.objectid import ObjectId

app = Flask(__name__)
#CORS(app)

# instantiate 
app.config.from_object(__name__)

# enable CORS
CORS(app, resources={r'/*': {'origins': '*'}})

app.config['MONGO_DBNAME'] = 'restdb'
app.config['MONGO_URI'] = 'mongodb://localhost:27017/restdb'

mongo = PyMongo(app)

@app.route('/dessert', methods=['POST'])
def add_dessert():
  dessert = mongo.db.desserts
  name = request.json['name']
  calories = request.json['calories']
  dessert_id = dessert.insert({
    'name': name, 
    'calories': calories
})
  new_dessert = dessert.find_one({'_id': dessert_id })
  output = {
    'name' : new_dessert['name'], 
    'calories' : new_dessert['calories']
}
  return jsonify({'result' : output})

@app.route('/dessert', methods=['GET'])
def get_all_desserts():
  dessert = mongo.db.desserts
  output = []
  for s in dessert.find():
    s['_id'] = str(s['_id'])
    output.append({'_id' : s['_id'], 
                   'name' : s['name'], 
                   'calories' : s['calories']
    })
  return jsonify({'data' : output})

@app.route('/dessert/<dessert_id>', methods=['GET'])
def get_one_dessert(dessert_id):
  dessert = mongo.db.desserts
  s = dessert.find_one({"_id" : ObjectId(dessert_id)})
  s['_id'] = str(s['_id']) 
  if s:
    output = {'_id' : s['_id'], 'name' : s['name'], 'calories' : s['calories']}
  else:
    output = "No such name"
  return jsonify({'result' : output})

@app.route('/dessert/<dessert_id>', methods=['DELETE'])
def delete_one_dessert(dessert_id):
  dessert = mongo.db.desserts
  s = dessert.find_one({"_id" : ObjectId(dessert_id)})
  s['_id'] = str(s['_id'])
  dessert.remove({"_id" : ObjectId(dessert_id)}) 
  if s:
    output = {'_id' : s['_id'], 'name' : s['name'], 'calories' : s['calories']}
  else:
    output = "No such name"
  return jsonify({'result' : output})

if __name__ == '__main__':
    app.run(debug=True)

1 Ответ

1 голос
/ 14 января 2020

Если я правильно понял, вы хотите видеть во внешнем интерфейсе вновь добавленный элемент, включая сгенерированный идентификатор, после отправки его в бэкэнд, верно?

Итак, вы можете просто просто вызовите fetchItems (), как только вы завершите публикацию нового элемента. Он автоматически обновит массив отображаемых элементов, включая недавно добавленный идентификатор.

Свойство ID создается при добавлении элемента в базу данных, поэтому его невозможно получить, пока сервер не предоставит вернемся к интерфейсу.

axios.post('http://localhost:5000/dessert', {
    name: this.editedItem.name,
    calories: this.editedItem.calories
}).then(response => {
    this.fetchItems()
})

Это означает, что после завершения POST снова вызовите fetchItems ().

...