【发布时间】:2018-02-25 17:50:47
【问题描述】:
恐怕是 VueJs、Vuex 和 MongoDB 的一些初学者问题
我无法正确设置删除功能。将帖子添加到我的状态后出现此错误:
对于模型路径“_id”处的值“未定义”,转换为 ObjectId 失败 “发布”“
一旦我刷新页面,它就会完美运行。我知道这是因为一旦添加,除非我刷新浏览器(这会触发“从后端获取所有帖子”功能),否则我新添加的帖子没有“_id”键。
在这里和那里阅读了很多类似的问题,但我没能找到我能真正理解并适应我的情况的东西。如何强制服务器返回 _id 密钥并更新我的商店客户端,这样我就不必刷新页面来获取它?
我的 NewPost.vue 组件:
<template>
<div class="posts">
<h1>Add Post</h1>
<div class="form">
<div>
<input type="text" name="title" placeholder="TITLE" v-model="title">
</div>
<div>
<textarea rows="15" cols="15" placeholder="DESCRIPTION" v-model="description"></textarea>
</div>
<div>
<button class="app_post_btn" @click="addPost">Add</button>
</div>
</div>
</div>
</template>
<script>
import PostsService from "@/services/PostsService";
export default {
name: "NewPost",
data() {
return {
title: "",
description: ""
};
},
methods: {
addPost() {
const newPost = {
title: this.title,
description: this.description
};
this.$store.dispatch("ADD_POST", newPost);
this.$router.push({ name: "Posts" });
}
}
};
</script>
Posts.vue 组件:
<template>
<div class="container posts"
:class= "{'night-mode': nightMode}">
<h1>Posts</h1>
<div class="row">
<b-card
v-if="posts"
v-for="post in posts"
:key="post.id"
:title="post.title"
img-src="https://lorempixel.com/600/300/food/5/"
img-alt="Image"
img-top
tag="article"
style="max-width: 20rem;"
class="mb-2 mr-5">
<p class="card-text">
{{post.description}}
</p>
<div class="card-actions">
<b-button size='lg' variant="outline-danger" @click="deletePost(post._id)">Delete</b-button>
<b-button size='lg' variant="outline-success" :to="{ name: 'EditPost', params: { id: post._id } }">Edit Post</b-button>
</div>
</b-card>
</div>
</div>
</template>
<script>
import PostsService from "../services/PostsService";
import axios from "axios";
export default {
name: "Posts",
data() {
return {};
},
methods: {
deletePost(id) {
return this.$store.dispatch("DELETE_POST", id);
}
},
computed: {
nightMode() {
return this.$store.getters.getNightMode;
},
posts() {
return this.$store.getters.posts;
}
},
};
</script>
还有这样的商店:
import Vuex from "vuex";
import Vue from "vue";
import axios from "axios";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
nightMode: false,
posts: []
},
mutations: {
toggleNightMode(state, payload) {
state.nightMode = payload;
},
CURRENT_POSTS(state, { posts }) {
state.posts = posts;
},
ADD_POST(state, { newPost }) {
state.posts.unshift({ ...newPost });
},
DELETE_POST(state, id) {
for (let post of state.posts) {
if (post._id === id) {
state.posts.splice(state.posts.indexOf(post), 1);
}
}
}
},
actions: {
GET_CURRENT_POSTS({ commit }) {
const url = "http://localhost:8081/posts";
return axios
.get(url)
.then(response => {
commit("CURRENT_POSTS", { posts: response.data.posts });
})
.catch(error => console.log(error));
},
DELETE_POST({ commit }, id) {
const url = "http://localhost:8081/posts/";
return axios
.delete(url + id)
.then(response => {
console.log(response);
commit("DELETE_POST", id);
})
.catch(error => console.log(error));
},
ADD_POST({ commit }, newPost) {
const url = "http://localhost:8081/posts/";
commit("ADD_POST", { newPost });
return axios
.post(url, newPost)
.then(response => {
console.log(response);
})
.catch(error => console.log(error));
}
},
getters: {
getNightMode: state => state.nightMode,
posts: state => state.posts
}
});
非常感谢大家!
编辑:服务器端代码
server/src/app.js
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const morgan = require("morgan");
const app = express();
app.use(morgan("combined"));
app.use(bodyParser.json());
app.use(cors());
app.listen(process.env.PORT || 8081);
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/posts");
var db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error"));
db.once("open", function(callback) {
console.log("Connection Succeeded");
});
var Post = require("./models/post");
// Fetch all posts
app.get("/posts", (req, res) => {
Post.find({}, "title description", function(error, posts) {
if (error) {
console.error(error);
}
res.send({
posts: posts
});
}).sort({ _id: -1 });
});
// Add new post
app.post("/posts", (req, res) => {
var db = req.db;
var title = req.body.title;
var description = req.body.description;
var new_post = new Post({
title: title,
description: description
});
new_post.save(function(error) {
if (error) {
console.log(error);
}
return axios
.post(url, newPost)
.then(response => {
console.log(newPost);
res.send({
success: true,
message: "Post saved successfully!"
});
});
});
//fetch a single post
app.get("/post/:id", (req, res) => {
var db = req.db;
Post.findById(req.params.id, "title description", function(error, post) {
if (error) {
console.log(error);
}
res.send(post);
});
});
// Update a post
app.put("/posts/:id", (req, res) => {
var db = req.db;
Post.findById(req.params.id, "title description", function(error, post) {
if (error) {
console.error(error);
}
post.title = req.body.title;
post.description = req.body.description;
post.save(function(error) {
if (error) {
console.log(error);
}
res.send({
success: true
});
});
});
});
// Delete a post
app.delete("/posts/:id", (req, res) => {
var db = req.db;
Post.remove(
{
_id: req.params.id
},
function(err, post) {
if (err) res.send(err);
res.send({
success: true
});
}
);
});
server/src/models/post.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var PostSchema = new Schema({
title: String,
description: String
});
var Post = mongoose.model("Post", PostSchema);
module.exports = Post;
【问题讨论】:
-
请出示相关的服务器端代码
标签: javascript mongodb vue.js vuex