メッセージ

17632 ワード

コメントは通常のpost methodリクエストに追加できますが、AJAXがすぐにページをリフレッシュするのを見たくありません.これがAJAXのハイライトです
project
youtube
  |views
   *|videoDetail.pug
 *|routes.js
  |routers
   *|apiRouter.js
  |controllers
   *|videoController.js
  |assets
    |js
     *|main.js
     +|addComment.js
videoDetail.pug
videodetail pageにメッセージを残すことができるフォームを追加します.formの位置はそれぞれ希望の位置に置けばいいです
  • form
    通常のformとは異なり、actionまたはmethod propertyは定義されていません.これは、ページをリフレッシュするのではなく、データベースにコメントを登録しているからです.AJAXで処理するのですこの方法については後述する.
  • input name
    入力nameもform propertyと同じ理由で入力する必要はありません.
  • each comment in video.comments
    そのまま使えますが、コメントの特性で最新のコメントを一番上に出したいならビデオですcomments.reverse()を使用して、アレイを反転します.
  • form.video__add-comment#jsCommentForm
      input(type="text", placeholder="댓글 작성")
    
    ul.video__comments#jsCommentList
      each comment in video.comments
        li #{comment.text}
    routes.js
    const ADD_COMMENT = '/:id/comment';
    
    const routes = {
      addComment: ADD_COMMENT;
    }
    
    export default routes;
    videoController.js
  • postAddComment
    合成されたコメントを受信してデータベースに追加する関数としてPostAddCommentを追加します.
  • videoDetail
    ビデオ要素を受信する過程で、ビデオに格納されているコメントをテンプレートに渡すためにコメントも入力しました.また、userのavatarまたはnameを使用するには、commentのUserコンテンツを入力する必要があります.
  • Promise.all
    videDetail関数では、Promiseはコメント配列内の各コメント要素のユーザーコンテンツを埋め込むために使用されます.allを使用します.Promiseだからallを無効にしてasync/awaitのみを使用すると、すべてのコメントを待つことなく空の配列のみが渡されます.
  • import Comment from '../models/Comment';
    
    export const postAddComment = async(req, res) => {
      const {
        params:{id},
        body:{comment},
        user
      }=req;
      
      try{
        const video = await Video.findById(id);
        const newComment = await Comment.create({
     	  text: comment,
          video: video.id,
          creator: user._id
        });
        video.comments.push(newComment.id);
        video.save();
        res.status(200);
      }catch(){
        res.status(400);
      }finally{
        res.end();
      }
    }
    
    export const videoDetail = async(req, res) => {
      /*생략했지만 try-catch문에 넣어주세요.*/
      const {params:{id}} = req;
      
      const video = await Video.findById(id)
        .populate("creator")
        .populate("comments");
      const comments = await Promise.all(video.comments.map(async comment => await Comment.findById(comment.id).populate('creator'));
    
      res.render("videoDetail", {video, commments});
      /*생략*/
    }
    apiRouter.js
    import {postAddComment} from '../controllers/videoController';
    
    apiRouter.post(routes.addComment, postAddComment);
    addComment.js
    axiosインストール
    端末への入力%npm install axiosaxios
    axiosの役割はfetchと同様で、次のオプションをオブジェクトに渡すことで使用できます.
  • url
    fetchとは異なり、アドレス全体を入力する必要はありません.
  • method
    methodを表し、GETやPOSTを使用することができます.
  • data
    req.これはbodyが含む情報を意味します.nameとvalueをオブジェクトとしてサーバに渡します.
  • addComment.js
  • addComment関数
    コメントを作成し、データベースに追加したコメントをすぐにテンプレートに適用した場合は良いですが、情報が変更前の状況を反映しているため、リフレッシュしないと追加したコメントはすぐに反映されないため、JavaScript trickを使用してリアルタイムで追加したテンプレートを作成します.htmlのみを使用して追加し、その後再接続すると、実際のサーバからアプリケーション効果を得ることができます.
  • response
    axios入力アドレスからの応答が受信されると、ビデオコントローラによって記述された論理応答ステータスコードに従う.statusに含まれます.200は正常処理、400はエラー発生です.このコードを使用してjavascript trickを使用します.fake dataでも登録されていない投稿を見せることはできません
  • const commentForm = document.querySelector('#jsCommentForm');
    const commentList = document.querySelector('#jsCommentList');
    
    const addComment = (comment) => {
      const comment = document.createElement('li');
      comment.innerHTML = comment;
      //댓글이 최신순으로 위에 올라오길 원하면 appendChild가 아니라 prepend method를 사용하시면 됩니다.
      commentList.appendChild(comment);
    }
    
    async function handleAddComment (event){
      //페이지의 리로딩 방지
      event.preventDefault();
      const commentInput = commentForm.querySelector('input');
      const comment = commentInput.value;
      commentInput.value = '';
      const videoId = window.location.href.split("/videos/")[1];
      const response = await axios({
        url:`/api/${videoId}/comment`,
        method: "POST",
        data:{
          comment
        }
      });
      
      if(response.status === 200){
        addComment(comment);
      }
    }
    
    function init(){
      commentForm.addEventListener('submit', handleAddComment);
    }
    
    if(commentForm){
      init();
    }
    main.js
    import './addComment.js';