[39][23.11.16][구디아카데미 후기/국비지원 IT개발자취업/김승수 선생님]

DANA·2023년 11월 16일

KDT-구디아카데미

목록 보기
39/56

firebase.js

// Firebase 앱 초기화를 위한 모듈 가져오기
import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.22.1/firebase-app.js';

// Firebase 구성 정보
const firebaseConfig = {
  apiKey: 
  authDomain: 
  projectId: 
  storageBucket: 
  messagingSenderId: '
  appId: 
};

// Firebase 앱 초기화 및 구성 정보 전달
export const app = initializeApp(firebaseConfig);
import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.22.1/firebase-app.js';
  • Firebase 앱 초기화를 위해 필요한 initializeApp 함수를 firebase-app.js 모듈에서 가져옴
const firebaseConfig = {
  apiKey: 
  authDomain: 
  projectId: 
  storageBucket: 
  messagingSenderId: '
  appId: 
};
  • Firebase 프로젝트를 초기화하기 위한 구성 정보
    : 프로젝트의 API 키, 인증 도메인, 프로젝트 ID, 스토리지 버킷, 메시징 발신자 ID, 앱 ID 포함
export const app = initializeApp(firebaseConfig);
  • initializeApp 함수를 사용하여 Firebase 앱을 초기화하고, 구성 정보를 전달
  • 이 초기화된 앱 객체(app)는 다른 Firebase 서비스를 사용할 때 필요한 기본 객체

라우터

  • 네트워킹 라우터
    : 네트워킹 측면에서 라우터는 서로 다른 컴퓨터 네트워크를 함께 연결하는 장치입니다. 주요 기능은 이러한 네트워크 간에 데이터 패킷을 전달하는 것입니다. 라우터는 OSI 모델의 네트워크 계층(3계층)에서 작동하며 라우팅 테이블을 사용하여 데이터 전달을 위한 최상의 경로를 결정

  • 웹 개발 라우터
    : 웹 개발에서 라우터는 웹 애플리케이션 내 탐색을 관리하는 데 도움이 되는 메커니즘입니다. 이는 전체 애플리케이션이 단일 웹 페이지에서 실행되고 전체 페이지를 다시 로드할 필요 없이 콘텐츠가 동적으로 변경되는 SPA(단일 페이지 애플리케이션)와 관련되는 경우가 많습니다


GET home page.
express가 Restful API를 지원해서 웹 서비스를 제공할 수 있게 해준다.(서블릿, JSP)
router는 페이지 전환 해주는 API로 - 화면 전환 처리 이벤트
get함수의 첫번째 파라미터가 요청에 대한 URL 주소이다.
URL주소마다 자바단에서는 메소드를 설계(구현)해야 한다.

아래 get요청에 대한 첫번째 자리는 요청에 따른 URL 패턴 이름이다.
이름을 가지고 메소드를 나눈다 - 프레임워크(스프링)에서는 그렇게 해준다
그래서 라우터가 눈에 보이지 않는 거다

첫번째 파라미터가 요청객체(request)이다. - 정보 담기, 사용자가 입력한 값을 받아옴, 요청이 유지되는 동안에 유지해줌
둘 파라미터 응답객체(response)이다 - mime type - 브라우저 확장자는 의미없다. 페이지 이동처리를 한다 - 라우팅이네
확장자가 jsp이더라도 application/json으로 되어 있다면 JSON인거다
application/ms-word

함수로 나누어지지 않은 대신에 세번째 인자인 next를 통해서 다른 서비스를 호출해준다???

express프레임워크에서는 request, response제공해줌
둘 다른 서비스를 요청하기 위해서 next도 제공해줌
next통해서 다른 서비스 즉 다른 미들웨어 연결도 가능함

Restful지원받을 수 있다 - 웹서비스구현하고 제공할 수있다.
express역할을 하는 것이 서블릿이다.

router.post();


index.js

  • Node.js의 Express 프레임워크를 사용하여 라우팅을 정의
// 웹 프레임워크 express 모듈 가져옴
var express = require('express');
// Express 라우터의 인스턴스를 생성
var router = express.Router();

// 루트 경로에 대한 GET 요청에 대한 핸들러
router.get('/', function(req, res, next) {
  // 'index' 템플릿에 데이터를 전달하여 페이지를 렌더링
  res.render('index', { title: '도서국리스트', pageName: "home.ejs" });
});

// '/login' 경로에 대한 GET 요청에 대한 핸들러
router.get('/login', function(req, res, next) {
  // 'auth/login.ejs' 템플릿에 데이터를 전달하여 로그인 페이지를 렌더링
  res.render('index', { title: '로그인', pageName: "auth/login.ejs" });
});

// '/board' 경로에 대한 GET 요청에 대한 핸들러
router.get('/board', function(req, res, next) {
  // 'board/list.ejs' 템플릿에 데이터를 전달하여 글 목록 페이지를 렌더링
  res.render('index', { title: '글목록', pageName: "board/list.ejs" });
});

// '/board/write' 경로에 대한 GET 요청에 대한 핸들러
router.get('/board/write', function(req, res, next) {
  // 'board/write.ejs' 템플릿에 데이터를 전달하여 글 작성 페이지를 렌더링
  res.render('index', { title: '글쓰기', pageName: "board/write.ejs" });
});

// '/board/:id' 경로에 대한 GET 요청에 대한 핸들러
router.get('/board/:id', function(req, res, next) {
  // 동적으로 파라미터 'id'를 받아 'board/read.ejs' 템플릿에 데이터를 전달하여 상세보기 페이지를 렌더링
  let id = req.params.id;
  res.render('index', { title: '상세보기', pageName: "board/read.ejs", id:id });
});

// '/board/update/:id' 경로에 대한 GET 요청에 대한 핸들러
module.exports = router;
router.get('/', function(req, res, next)
router.get( )
  • Express 라우터에게 HTTP GET 요청에 대한 핸들러를 등록하는 부분. get 메서드는 클라이언트로부터 들어온 GET 요청을 처리할 때 사용
  • HTTP GET 요청
    : 월드 와이드 웹에서 특정 자원으로부터 데이터를 요청하는 방법 중 하나. 웹 서버에서 HTTP GET 요청을 위한 "처리기"는 특정 경로나 URL에 GET 요청이 있을 때 응답을 생성
    : Express.js나 이와 유사한 웹 프레임워크에서 HTTP GET 요청에 대한 "핸들러"는 특정 경로에 GET 요청이 있을 때 실행되는 콜백 함수. 서버가 해당 요청에 어떻게 응답해야 하는지를 정의하며 HTML, JSON 또는 일부 다른 데이터를 클라이언트에 다시 보내는 것을 포함하는 경우가 많음

'/' : 라우터가 처리하는 경로를 지정. 여기서는 루트 경로를 의미하며, 홈페이지에 접근했을 때 이 핸들러가 실행

function(req, res, next) { ... }
  • 요청을 처리하는 함수로, 클라이언트의 요청(req), 서버의 응답(res), 그리고 다음 미들웨어나 라우터로 제어를 전달하는 콜백 함수(next)를 인자로 받음
res.render('index', { title: '도서국리스트', pageName: "home.ejs" }
  • res
    : 이 개체는 Express 앱이 HTTP 요청을 수신할 때 보내는 HTTP 응답을 나타냄(응답에 대한 결과가 꼭 html일 필요는 없음)
  • .render
    : 이 메서드는 뷰(템플릿)를 렌더링하고 HTML을 HTTP 응답으로 보내는 데 사용
    : render함수 호출하면 화면을 그려준다
    → 그래서 파라미터 자리에는 반드시 html파일이 온다
  • 'index'
    : 렌더링할 뷰 또는 템플릿의 이름을 지정(여기서는 앱이 렌더링할 "index"라는 뷰가 있다고 가정)
  • { title: 'Library list', pageName: "home.ejs" }
    : 이 객체는 뷰에 전달될 데이터를 나타내는 키-값 쌍의 집합
    : 화면 처리에 대한 엔진으로 ejs(Embedded JavaScript)가 선택됨(뷰 엔진)
let id = req.params.id;
  • 요청 매개변수(req.params)에서 'id' 매개변수 값을 추출. Express에서 경로 매개변수는 요청(req)의 params 객체에 저장
module.exports = router;
  • 다른 파일에서 사용할 수 있도록 라우터 인스턴스를 내보내는 데 사용

users.js

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function (req, res, next) {
  res.send('respond with a resource');
});
router.get('/join', function (req, res, next) {
  res.render('index', { title: '회원가입', pageName: 'users/join.ejs' });
});
router.get('/cart', function (req, res, next) {
  // res.send();파라미터 문자열이 출력되고 나는 장바구니 화면을 출력할거니까 render함수 호출함
  res.render('index', { title: '장바구니', pageName: 'users/cart.ejs' });
});
router.get('/mypage', function (req, res, next) {
  // res.send();파라미터 문자열이 출력되고 나는 장바구니 화면을 출력할거니까 render함수 호출함
  res.render('index', { title: 'MyPage', pageName: 'users/mypage.ejs' });
});
//회원정보 수정
router.get('/update', function (req, res, next) {
  res.render('index', { title: '회원정보수정', pageName: 'users/update.ejs' });
});

module.exports = router;

home.ejs

  • EJS(Embedded JavaScript) 템플릿 엔진을 사용하여 HTML 페이지에 다른 파일의 내용을 포함
<div class="row my-5">
  <div class="col">
    <%-include("book/bookList.ejs")%>
  </div>
</div>
<div class="row my-5">

Bootstrap에서 제공하는 그리드 시스템을 사용하여 페이지의 레이아웃을 설정하는 부분입니다. row 클래스는 행을 나타내며, my-5 클래스는 위아래 여백을 지정합니다.

<div class="col">

Bootstrap의 그리드 시스템에서 컬럼을 나타내는 부분으로, 전체 너비를 차지합니다.

<%- include("book/bookList.ejs") %>

EJS의 include 문을 사용하여 외부 파일인 "book/bookList.ejs"의 내용을 포함시킵니다. 이를 통해 코드의 재사용성을 높일 수 있습니다.

login.ejs

<div class="row my-5 justify-content-center">
  <div class="col-8 col-md-6 col-lg-4">
    <h3 class="text-center mb-5">로그인</h3>
    
    <!-- 로그인 폼 시작 -->
    <form name="frm" method="post">
    
      <!-- 이메일 입력 -->
      <div class="input-group my-2">
        <div class="input-group-text">이메일</div>
        <input class="form-control" name="email" value="tomato@hot.com" />
      </div>
      
      <!-- 비밀번호 입력 -->
      <div class="input-group">
        <div class="input-group-text">비밀번호</div>
        <input
          class="form-control"
          name="password"
          type="password"
          value="12345678"
        />
      </div>
      
      <!-- 로그인 버튼 -->
      <div class="my-3">
        <button class="btn btn-success w-100">로그인</button>
      </div>
      
      <!-- 회원가입 링크 -->
      <!-- 회원가입 링크경로는 반드시 router/user.js를 확인할 것 -->
      <div class="text-end mt-3"><a href="/users/join">회원가입</a></div>
    </form>
    <!-- 로그인 폼 끝 -->
    
  </div>
</div>


<script type="module">
  // Firebase 모듈 및 인증 관련 메서드 가져오기
  import { app } from "/javascripts/firebase.js";
  import { getAuth, signInWithEmailAndPassword } from "https://www.gstatic.com/firebasejs/9.22.1/firebase-auth.js"
  
  // Firebase 앱 초기화 및 인증 객체 생성
  const auth = getAuth(app); //apikey(내 정보)
  console.log(auth);
  
  // 폼 제출 이벤트 핸들러
  // 로그인 버튼 눌렀을 때
  $(frm).on("submit", function(e){
    console.log('로그인버튼 클릭');
    e.preventDefault();
    
    // 사용자가 화면에 입력한 이메일과 비밀번호
    let email = $(frm.email).val();
    let password = $(frm.password).val();
    console.log(`${email} ${password}`);
    
    // Firebase를 사용하여 이메일과 비밀번호로 로그인
    // 사용자가 양식을 작성하면 아래 메서드를 호출
    signInWithEmailAndPassword(auth, email, password)
    // then - 응답을 다 받을 때까지 기다렸다가 response를 파이어베이스 서버에 담는다
    .then((response) => {
      // 로그인 성공 시 사용자 정보 출력
      const user = response.user;
      
      
      console.log(`user ===> ${JSON.stringify(user)}`);
      console.log(`uid ====> ${user.uid}`);
      console.log(`email ====> ${user.email}`);
      
      // 로컬 스토리지에 사용자 정보 저장 후 홈페이지로 이동
      localStorage.setItem("uid",`${user.uid}`)
      localStorage.setItem("email",`${user.email}`)
      location.href="/";
    })
    .catch((error) => {
      // 로그인 실패 시 에러 처리
      const errorCode = error.code;
      const errorMessage = error.message;
      console.error(`로그인 실패: ${errorCode} - ${errorMessage}`);
    });
  })
</script>

header.ejs

<!-- 스타일 정의 -->
<style>
  @media screen and (max-width: 960px) {
    #slider-div {
      display: none;
    }
  }
</style>

<!-- 네비게이션 바 -->
<nav class="navbar navbar-expand-lg bg-success navbar-dark">
  <div class="container-fluid">
    <!-- 사이트 로고 -->
    <a class="navbar-brand" href="#">세상의 모든 검색</a>
    <!-- 햄버거 메뉴 토글 버튼 -->
    <button
      class="navbar-toggler"
      type="button"
      data-bs-toggle="collapse"
      data-bs-target="#navbarSupportedContent"
      aria-controls="navbarSupportedContent"
      aria-expanded="false"
      aria-label="Toggle navigation"
    >
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <!-- 네비게이션 링크 -->
      <ul class="navbar-nav me-auto mb-2 mb-lg-0">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="#">Home</a>
        </li>
        <li class="nav-item" id="notice">
          <a class="nav-link active" aria-current="page" href="/board">게시판</a>
        </li>
        <li class="nav-item" id="youtube">
          <a class="nav-link active" aria-current="page" href="#">유튜브</a>
        </li>
        <li class="nav-item" id="movie">
          <a class="nav-link active" aria-current="page" href="#">영화</a>
        </li>
        <li class="nav-item" id="cart" style="display: none">
          <a class="nav-link active" aria-current="page" href="/users/cart">장바구니</a>
        </li>
      </ul>

---------------[[ users section ]]--------------------
      <!-- 로그인/로그아웃 링크 -->
      <div class="d-flex">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <li class="nav-item" id="login">
            <a class="nav-link active" aria-current="page" href="/login">로그인</a>
          </li>
          <li class="nav-item" id="email" style="display: none">
            <a class="nav-link active" aria-current="page" href="/users/mypage">MyPage</a>
          </li>
          <li class="nav-item" id="logout" style="display: none">
            <a class="nav-link active" aria-current="page">로그아웃</a>
          </li>
        </ul>
      </div>
    </div>
  </div>
</nav>
---------------[ end of Navbar ]--------------------


---------------[[ 캐러셀 추가 ]]--------------------
<!-- 슬라이더 섹션 -->
<div id="slider-div">
  <div>
    <img src="/images/header01.png" alt="직장인을위한 챗GPT" width="100%" />
  </div>
  <div>
    <img src="/images/header02.png" alt="데이터분석을 배우는" width="100%" />
  </div>
  <div>
    <img src="/images/header03.png" alt="FastAPI를 사용한" width="100%" />
  </div>
  <div>
    <img src="/images/header04.png" alt="챗GPT업무..." width="100%" />
  </div>
</div>
---------------[[ 캐러셀 추가 끝 ]]--------------------


---------------[[ 캐러셀 이벤트 처리 ]]--------------------

<!-- Firebase 및 로그아웃 스크립트 -->
  // ES6 모듈 형식을 사용하고 있는 스크립트
  // Firebase에서 제공하는 모듈로부터 인증 및 로그아웃과 관련된 함수들을 가져옴
  // 현재 파이어베이스 콘솔에서 지원하는 Authentification빌드 사용 중
  // export const app = initializeApp(firebaseConfig)
  // firebase.js에 정의되어 있으므로 import문이 필요함
<script type="module">
  import { app } from "/javascripts/firebase.js";
  import { signOut, getAuth } from "https://www.gstatic.com/firebasejs/9.22.1/firebase-auth.js"

  // Firebase 앱에서 인증 객체 가져옴
  const auth = getAuth(app);
  console.log(auth);

  // 로그아웃 버튼이 클릭되었을 때의 동작을 정의
  $("#logout").on("click", () => {
    // Firebase 서버에서 로그아웃 처리
    auth.signOut();
    signOut(auth).then(() => {
 console.log("로그아웃 성공 - 구글서버");
      })
    
    // 로그아웃 중 오류가 발생한 경우 콘솔에 오류 메시지를 출력
      .catch((error) => {
        console.log(error); 
      });
    localStorage.clear(); 
    location.href = "/"; 
  });
</script>

// 로컬 스토리지에서 이메일 정보를 가져와서 콘솔에 출력
console.log(`header - ${localStorage.getItem("email")}`);

// 이메일 정보가 로컬 스토리지에 있을 경우 실행됩니다.
if (localStorage.getItem("email")) {
  // 콘솔에 메시지를 출력합니다.
  console.log("여기로 들어왔니?");
  
  // ID가 'login', 'logout', 'email', 'cart'인 요소들을 토글합니다.
  $("#login,  #logout, #email, #cart").toggle();
  
  // ID가 'email'인 요소의 하위 'a' 태그의 HTML 내용을 로컬 스토리지에서 가져온 이메일로 설정합니다.
  $("#email a").html(localStorage.getItem("email"));
}

// 슬라이더를 초기화하고 설정합니다.
applySlider = () => {
  console.log("여기");

  // ID가 'slider-div'인 요소를 Slick 슬라이더로 변환합니다.
  $("#slider-div").slick({
    slide: "div", // 슬라이드로 사용할 HTML 요소
    infinite: true, // 무한 스크롤
    slidesToShow: 1, // 보여질 슬라이드 개수
    slidesToScroll: 1, // 스크롤 시 이동할 슬라이드 개수
    speed: 100, // 슬라이딩 속도 (단위: 밀리초)
    arrows: true, // 화살표 표시 여부
    dots: true, // 점 표시 여부
    autoplay: true, // 자동 재생 여부
    autoplaySpeed: 10000, // 자동 재생 간격 (단위: 밀리초)
    pauseOnHover: true, // 마우스 호버 시 자동 재생 일시 정지 여부
    vertical: false, // 수직 방향 슬라이드 여부
    prevArrow: "<button type='button' class='slick-prev'><div style='font-size:1.5rem;color:white;'>&lt;</div></button>",
      nextArrow: "<button type='button' class='slick-next'><div style='font-size:1.5rem;color:white;'>&gt;</div></button>",
      dotsClass: "slick-dots", //아래 나오는 페이지네이션(점) css class 지정
      draggable: true, //드래그 가능 여부
      responsive: [
        // 반응형 웹구현 옵션
        {
          breakpoint: 960, //화면 사이즈 960px
          settings: { slidesToShow: 3 }, //위에 옵션이 디폴트 , 여기에 추가하면 그걸로 변경
        },
        {
          breakpoint: 768, //화면 사이즈 768px
          settings: { slidesToShow: 2 }, //위에 옵션이 디폴트 , 여기에 추가하면 그걸로 변경
        },
      ],
    });
  };
  applySlider();
</script>
---------------[[ 캐러셀 이벤트 처리 끝 ]]--------------------

footer.ejs

<div class="row my-5">
  <div class="col">
    <hr>
    <h5 class="text-center">
      Copyright 2023. 한빛출판사 all rights reserved.
    </h5>
  </div>
</div>

app.js

/*
웹 애플리케이션을 위한 기본적인 설정을 가지고 있다
모듈을 로딩하고  템플릿 엔진을 설정하여 라우터 설정함
파일 상단에는 사용할 모듈을 로딩하는 코드가 작성됨
외부 모듈을 해당 파일에서 사용하고 싶다면 require() 함수를 호출해야 함
자바의 입장에 서 보면 - Servlet, JSP
그중에 뭐? app.use(req,res,next)
app.get(req,res,next)
app.post(req,res,next)
*/
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
//라우트 코드를 로딩하는 코드임. require()함수를 사용하며
//로딩한 라우트 함수들을 지정된 변수로 사용할 수 있게 해줌
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
//express객체를 app변수로 선언함
var app = express();

// view engine setup
//익스프레스에서 사용할 템플릿 엔진을 설정하는 코드임
//__dirname은 현재 디렉토리를 의미하며 path.join()함수는 경로를 연결하는 기능을 함
app.set('views', path.join(__dirname, 'views'));
//ejs가 아닌 html확장자는 호출이 불가함 - app.js에 html 마임타입에 대한 설정이 없으니까
app.set('view engine', 'ejs'); //템플릿엔진의 종류(태그안에 데이터를 심음 -for문-자스태그섞어쓰기)
//파라미터에 지정된 인자를 실행하는 함수임
//여기서는 각각의 모듈을 사용하도록 설정함
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
//정적페이지의 물리적인 위치를 설정함
//static 을 붙여서 정적으로 처리함
app.use(express.static(path.join(__dirname, 'public')));
//라우트를 설정하는 코드임. 여기서 라우트는 url경로의 뒷부분을 의미함
//'/'와 관련된 라우트는 routes폴더의 index파일에 설정된 라우트 함수를 통해 처리됨
app.use('/', indexRouter); //index.js
// '/users'와 관련된 라우트는 users파일에 작성된 라우트 함수를 통해 처리됨 - MyPage, 대시보드, 장바구니
app.use('/users', usersRouter); // users.js

// catch 404 and forward to error handler
//use 함수는 get방식, post방식 구분없이 사용
//use함수는 왜 사용하지? 요청객체와 응답객체를 주입해주니까..
//요청-사용자가 입력한 값을 서버측에서 요청할 수 있다.
//응답 - 앞에 요청에 대한 처리 후 응답페이지의 이동이나 출력결과를 text or json형식 출력을 받아낸다.
//내장객체이고 express자동 주입해줌 - dependency injection - 클래스와 클래스, 라이브러리와 라이브러리
//next - 다음 미들웨어로 이동할 때 꼭 필요하다
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
  //res.send(msg)
  //res.render(html)
});

module.exports = app;

deptList.html

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>실습 - Handlebars[템플릿엔진]</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65"
      crossorigin="anonymous"
    />
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
      crossorigin="anonymous"
    ></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.1/handlebars.js"></script>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
  </head>
  <body>
    <!--  
        x-handlebars-template sub mime type은 표준이 아니다.???
        표준이 아니라는 건 재해석이 필요하다 - 모르는애
        핸들바스로 되어 있는 템플릿 컴파일 합니다.
    -->
    <script id="tb-dept" type="text/x-handlebars-template">
      <table class='table'>
        <!-- 헤더 영역 시작 -->
        <thead>
          <tr>
            <th scope='col'>부서번호</th>
            <th scope='col'>부서명</th>
            <th scope='col'>지역</th>
          </tr>
        </thead>
        <!--  헤더 영역 끝 -->
        <!--  데이터셋 추가하는 화면 제공되는 영역  시작 -->
        <tbody>
          {{#depts}}
            <tr>
              <td>{{deptno}}</td>
              <td>{{dname}}</td>
              <td>{{loc}}</td>
            </tr>
          {{/depts}}
        </tbody>
        <!--  데이터셋 추가하는 화면 제공되는 영역   끝 -->
      </table>
    </script>
  </body>
  <script>
    //핸들바스 템플릿을 가져옵니다.
    const tb_dept = $('#tb-dept').html();
    //여기서는 자바처럼 고급언어를 저급언어로 바꾸는 그런 컴파일 아님
    //뭔가 머지(병합)과정이 필요하다
    {{}} + <tr>....</tr> -> 그 안에 뭐가 있는데 ->  반복문
    화면과 로직을 분리한다
    자바스크립트 코드와 태그를 섞어쓰는건 유지보수에 좋지 않다. - 개발에도 좋은 모양새는 아닌것 같다
    라이브러리라는 건 도구 모음이다.
    const template = Handlebars.compile(tb_dept);
    //핸들바스 템플릿에 바인딩될 데이터셋 입니다 - Array
    const data = {
      depts: [
        { deptno: 10, dname: '개발1팀', loc: '서울' },
        { deptno: 20, dname: '운영팀', loc: '제주' },
        { deptno: 30, dname: '품질관리팀', loc: '세종' },
      ],
    };
    //핸들바 템플릿에 데이터를 바인딩해서 html를 새로 생성함
    const deptList = template(data);
    //위에서 생성된 템플릿을 body태그에 붙인다(추가)
    $('body').append(deptList);
  </script>
</html>
<!-- 
  https://handlebarsjs.com/api-reference/data-variables.html#index
  
    select된 결과가 3건이라면 for문을 돌려서 한개로우씩 3번 반복되어야 한다.
    문제제기 :  자바코드와  태그코드가 섞이는게 불편하다
    :가독성 - DOM Tree-> 태그로만 작성해 본다(유리)
    :디자인과 로직은 분리되어야 한다.
    :좌중괄호 우중괄호 짝이 안맞으면 500번 에러 발생
    대안으로 템플릿엔진을 지원하게 되었다
 -->

0개의 댓글