<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="/static/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<!-- Font Awesome CSS -->
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.5.1.js"
integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js"
integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.4.0/socket.io.js"></script>
<link href="/static/mystyle.css" rel="stylesheet">
<title>스파르타 쇼핑몰 | 상품 목록</title>
<script>
$(document).ready(function () {
get_goods()
$("#categorySelect").on("change", function () {
get_goods($(this).val())
})
})
function sign_out() {
$.removeCookie('mytoken', { path: '/' });
$.removeCookie('userName', { path: '/' });
window.location.href = "/"
}
function get_goods(category) {
$("#goodsList").empty()
console.log(category)
$.ajax({
type: "GET",
url: `/api/goods${category ? "?category=" + category : ""}`,
data: {},
success: function (response) {
let goods = response["goods"]
for (let i = 0; i < goods.length; i++) {
make_card(goods[i])
}
}
})
}
function make_card(item) {
let htmlTemp = `<div>
<div class="card mb-2"token interpolation">${item["goodsId"]}'">
<div class="row no-gutters">
<div class="col-sm-5" style="background: #868e96;">
<img src="${item["thumbnailUrl"]}"
class="card-img-top h-100" alt="...">
</div>
<div class="col-sm-7 d-flex">
<div class="card-body flex-fill">
<div class="card-title mb-auto">
<h5 style="display: inline">${item["name"]}</h5>
<span class="card-price ml-2">$${number2decimals(item["price"])}</span>
</div>
<span class="badge badge-secondary">${item["category"]}</span>
<!-- <p class="card-text"><small class="text-muted">drink</small></p>-->
</div>
</div>
</div>
</div>
</div>`
$("#goodsList").append(htmlTemp)
}
function makeNoti(data) {
let htmlTemp = `<div class="alert alert-sparta alert-dismissible show fade" role="alert" id="customerAlert">
${data["userName"]}님이 방금 <a href="#" class="alert-link">${data["goodsName"]}</a>을 구매했어요!
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>`
$("body").append(htmlTemp)
}
function number2decimals(num) {
return (Math.round(num * 100) / 100).toFixed(2);
}
</script>
<style>
.card {
cursor: pointer;
}
html {
overflow: auto;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-dark bg-sparta justify-content-end">
<a class="navbar-brand" href="/goods">
<img src="/static/logo_big_tr.png" width="30" height="30" class="d-inline-block align-top" alt="">
스파르타 쇼핑몰
</a>
<button class="navbar-toggler ml-auto" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="true"
aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>
<div class="navbar-collapse collapse flex-grow-0 ml-auto" id="navbarSupportedContent" style="">
<ul class="navbar-nav mr-auto text-right">
<li class="nav-item" id="link-cart">
<a class="nav-link" href="/cart">
장바구니<i class="fa fa-shopping-cart ml-2" aria-hidden="true"></i>
</a>
</li>
<li class="nav-item" id="link-logout">
<a class="nav-link" data-toggle="modal" data-target="#signOutModal">
로그아웃<i class="fa fa-sign-out ml-2" aria-hidden="true"></i>
</a>
<div class="modal text-left" id="signOutModal" tabindex="-1" role="dialog"
aria-labelledby="signOutModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="signOutModalLabel">로그아웃</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
로그아웃하시면 장바구니가 사라져요!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-sparta" data-dismiss="modal">취소
</button>
<button type="button" class="btn btn-sparta" onclick="sign_out()">로그아웃하기
</button>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</nav>
<div class="wrap">
<div>
<div class="form-group row mr-0">
<label for="categorySelect" class="col-4 col-form-label">카테고리</label>
<select class="form-control col-8" id="categorySelect">
<option value="" selected>전체</option>
<option value="drink">음료</option>
<option value="food">음식</option>
</select>
</div>
</div>
<div id="goodsList" class="mb-5">
<div>
<div class="card mb-2" onclick="location.href='#'">
<div class="row no-gutters">
<div class="col-sm-5" style="background: #868e96;">
<img src="https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg"
class="card-img-top h-100" alt="...">
</div>
<div class="col-sm-7 d-flex">
<div class="card-body flex-fill">
<div class="card-title mb-auto">
<h5 style="display: inline">상품 1</h5>
<span class="card-price ml-2">$6.20</span>
</div>
<span class="badge badge-secondary">drink</span>
<!-- <p class="card-text"><small class="text-muted">drink</small></p>-->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<div class="form-group row mr-0">
<label for="categorySelect" class="col-4 col-form-label">카테고리</label>
<select class="form-control col-8" id="categorySelect">
<option value="" selected>전체</option>
<option value="drink">음료</option>
<option value="food">음식</option>
</select>
</div>
$(document).ready(function () {
get_goods()
$("#categorySelect").on("change", function () {
get_goods($(this).val())
})
})
--> 리스너 설정 --> categorySelect( 위에서 카테고리의 id )에서 change를 감지하면 이하의 function실행
--> get_goods메소드에 선택된 카테고리의 value를 요소로 넣어 실행 --> $(this).val()부분이 카테고리의 value를 리턴하는 부분
(아래에 후술 할 코드)
function get_goods(category) {
$("#goodsList").empty()
console.log(category)
$.ajax({
type: "GET",
url: `/api/goods${category ? "?category=" + category : ""}`,
data: {},
success: function (response) {
let goods = response["goods"]
for (let i = 0; i < goods.length; i++) {
make_card(goods[i])
}
}
})
}
--> goodsList는 위 사진의 모든 데이터들이 들어있는 list--> 실행되면 일단 이걸 한번 비움
--> $.ajax({}) 부분은 본인 서버에 request를 보내는 부분
--> request의 내용을 넣어서 보냄
1. 어떤 형식 일지
2. 어느 url로 보낼지
3. 어떤 data를 넣어 보낼지
4. request를 success했을 경우 반환되는 response에 대해 어떤 반응을 보일지
여기서는
1. get 타입
2. 'api/goods'로 보내는데, category로 받은 값이 있다면 'api/goods?category=카테고리값'으로 보내는 것으로 데이터까지 보냄
3. 따로 데이터를 넣어서 보내지는 않음
4. request를 통해 response를 받았을 경우, 해당 response에서 goods키에 해당하는 값을 가져와 하나씩 make_card메소드에 넣는다.
--> api/goods는 category에 해당하는 데이터를 mongoDB에서 json형태로 가져오는 api이기 떄문에 위와 같이 구성된다.
--> router폴더 내부에 있는 ./router/goods.js 파일
--> ../schemas/Goods에 있는 파일이 DB 연결에 해당하는 내용이 있는 파일이다.( 아마 다른 게시글에 있을 것이니 참고 )
const express = require("express");
const Goods = require("../schemas/Goods");
const router = express.Router();
router.get("/goods", async (req, res, next) => {
try {
const { category } = req.query;
const goods = await Goods.find({ category }).sort("-goodsId");
res.json({ goods: goods });
} catch (err) {
console.error(err);
next(err);
}
});
--> category를 url에 얹어서 보내면 해당 request에서 query로 category를 받는다. ( 비동기 할당방식 )
( '/api/goods?category=뭐시기' 형식 )
--> 받은 카테고리 데이터로 mongoDB에서 해당 데이터들을 찾아 가져온 후,
'goods'라는 이름의 키에 json형태로 데이터를 만들어 response한다.
--> 이렇게 reponse된 json데이터가 위의 코드의 get_goods메소드로 가서 make_card메소드에 하나씩 들어가 브라우저에 나타나는 것이다.
const goodsRouter = require("./routers/goods");
app.use("/api", [goodsRouter]);
--> 위와 같은 방식으로 메인 index.js에 해당 goods.js파일이 등록되어 있기 때문에 /api로 들어가야 일단 goods.js파일의 라우팅 영역에 들어가는 것이다.