【问题标题】:Vuetify datatable reload when performing CRUD operations执行 CRUD 操作时 Vuetify 数据表重新加载
【发布时间】:2020-01-13 19:46:53
【问题描述】:

我有一个执行 CRUD 操作的简单 vuetify 数据表。我正在使用 axios 和一个 mongo 数据库。当我添加一个新项目时,信息会正确显示在客户端并发布在 mongo 数据库中。但是,我无法访问 mongo 数据库的更新信息,尤其是 mongo 创建的 id,除非我重新加载网页。我是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)

【问题讨论】:

  • 发布您用于组件的标记/源代码可能会更好,而不是链接到 codepen.io(codepen 本身缺少任何使用的外部库)
  • 另外,您发布的帖子可以毫无问题地访问this.editedItem._id,但还必须重新加载网页才能访问this.editedItem._id,这是正确的还是您打错了?
  • 请发布您遇到问题的实际代码...codepen 显然不能用于重现您的问题;您说在 添加 项目后访问 mongo 数据库的信息时遇到问题,但 codepen 显示 添加 项目的 no 代码。 . 可能的答案是,无论您在哪里添加项目,都需要刷新数据。
  • @user1538301 感谢您的意见。我发布了可重现的示例。让我知道任何疑问。
  • 你的帖子输出不是缺少id吗?

标签: mongodb vue.js datatable axios vuetify.js


【解决方案1】:

如果我理解正确的话,你希望能够在前端看到新添加的项目,包括生成的ID,在发布到后端之后,对吧?

因此,您只需在完成发布新项目后调用 fetchItems()。它将自动更新显示项目的数组,包括新添加的 ID。

ID 属性是在项目添加到数据库时创建的,因此除非后端将其返回给前端,否则无法拥有它。

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

也就是说,一旦完成 POST,再次 fetchItems()。

【讨论】:

  • 我收到此错误:“错误:'response' 已定义但从未使用过 (no-unused-vars)”
  • 为了测试的目的,试着把它改成:axios.post('http://localhost:5000/dessert', { name: this.editedItem.name, calories: this.editedItem.calories }).then(response =&gt; { console.log(response.data) this.fetchItems() })让我们检查一下它是否会在控制台上打印响应然后调用this.fetchItems()
  • 我把括号弄错了,现在它可以正常工作了。
猜你喜欢
  • 2020-04-21
  • 2021-11-09
  • 1970-01-01
  • 2019-08-12
  • 2020-01-15
  • 2018-07-25
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多