Используйте запрос put для редактирования массива в массиве в Vue - PullRequest
0 голосов
/ 29 апреля 2020

Я создаю приложение типа блога, используя Vue, и одна из вещей, которые я пытаюсь сделать, - дать пользователям возможность комментировать пост. У меня возникли проблемы с использованием моего запроса apis PUT, чтобы добавить комментарии к сообщению. Вот как это настроено для предоставления некоторого контекста.

postSchema:

const postSchema = new mongoose.Schema({
    title:  {
        type: String,
        required: true
    },
    userPosted: {
        type: String,
    },
    datePosted: {
        type: Date,
        required: true,
        default: Date.now()
    },
    course: {
        type: String,
        default: ''
    },
    professor: {
        type: String,
        default: ''
    },
    post: {
        type: String,
        required: true
    },
    comments:
        [{
            commentedBy: {
                type: String
            },
            commentdate:{
                type: Date,
                default: Date.now()
            },
            usercomment: {
                type: String
            }
        }],
    likes: {
        type: Number,
        default: 0
    }
})

Post api для запроса PUT

router.put('/:id', async (req,res) => {
    try{
        //find post by id, update using request body, return updated post to 
        Post.findByIdAndUpdate({_id: req.params.id}, req.body).then(function(){
            //find updated post
            Post.findOne({_id: req.params.id}).then(function(post){
                res.send(post)
            }) 
        })
    } catch(err){
        res.send(err)
    }
})

страница раздела комментариев

  <form action="" v-if="isLoggedIn">
      <div class="d-flex bd-highlight">
           <!-- comment input field -->
           <div class="p-2 flex-grow-1 bd-highlight">
              <input type="text" class="form-control" placeholder="Comment here...">
           </div>
           <!-- submit button -->
           <div class="p-2 bd-highlight">
               <button class="btn btn-outline-dark">done</button>
           </div>
      </div>
  </form>
  <hr v-if="isLoggedIn">

  <!-- Comment section -->
  <h4 class="card-title">Comments</h4>
  <!-- single comment -->
  <div class="single-comment" v-for="(comment, i) in post.comments" :key="i">
  <!-- comment information -->
  <h6 class="card-subtitle mb-2 text-muted">Posted {{moment(comment.commentdate).fromNow()}} by {{comment.commentedBy}}</h6>
   <!-- comment content -->
   <p class="card-text comment-content">{{comment.usercomment}}</p>


</template>

<script>
export default {
    data() {
        return {
            id: this.$route.params.id,
            post: []
        }
    },
    async created() {
        return this.$http.get('http://localhost:3000/posts/' + this.id)
        .then(res => {
            this.post = res.data
        })
    }
}
</script>

Как вы можете видеть, я смоделировал это с комментариями, вложенными в пост, поэтому я технически редактирую пост при создании комментария. Запрос прекрасно работает в почтальоне, поэтому серверная часть настроена правильно, но у меня возникают проблемы с использованием Vue для достижения sh того, что я хочу.

Так выглядит секция комментариев.

enter image description here

1 Ответ

1 голос
/ 29 апреля 2020

В форме комментария вы можете использовать локальную переменную в своем компоненте для удержания комментария, когда пользователь вводит его. Мы также прикрепляем метод к кнопке для выполнения действия при нажатии:

  <form action="" v-if="isLoggedIn">
      <div class="d-flex bd-highlight">
           <!-- comment input field -->
           <div class="p-2 flex-grow-1 bd-highlight">
              <input type="text" class="form-control" placeholder="Comment here..." v-model="currentComment">
           </div>
           <!-- submit button -->
           <div class="p-2 bd-highlight">
               <button class="btn btn-outline-dark" @click="submitComment">done</button>
           </div>
      </div>
  </form>

Затем в части скрипта компонента:

<script>
export default {
    data() {
        return {
            currentComment: "", // Bucket for holding the comment temporarily
            id: this.$route.params.id,
            post: []
        }
    },
    async created() {
        return this.$http.get('http://localhost:3000/posts/' + this.id)
        .then(res => {
            this.post = res.data
        })
    }
    methods: {
        /* Our submit method for comments */
        async submitComment() {
            this.post.comments.push({
                commentedBy: /*The current user, wherever that is stored*/,
                commentdate: Date.now(),
                usercomment: this.currentComment // Our temporary value
            });
            return this.$http.put('http://localhost:3000/posts/' + this.id, this.post)
            .then(res => {
                /* Do some messaging and cleanup here (like emptying currentComment) */
            })
        }
    }
}
</script>

Вы не показываете, откуда в нашем примере идет текущий пользователь, поэтому commentedBy собирается поработать над ваша часть, чтобы получить данные в правильном месте.

...