(35) 23.11.10[JS]

DANA·2023년 11월 13일

KDT-구디아카데미

목록 보기
35/56

전개연산자1.js

// 전개 연산자(Spread Operator)

const fruits = ['🥝','🍓','🍅','🍎'];
console.log(fruits);

//... 전개연산자로 읽는다
//문자열이 출력된다
console.log(...fruits);

toObject = (a, b, ...c) => {
  return {//,는 열거형 연산자이다
    a:a, b:b, c:c,
  }
}
toObject2 = (a, b, ...c) => {
  //속성의 이름과 데이터의 이름이 같으면 축약형으로 가능하다
  return {//,는 열거형 연산자이다
    a, b, c,
  }
}

//실행문안에 다른 코드가 없으면 좀 더 축약할 수 있다.
toObject3 = (a, b, ...c) => ({a, b,c});


console.log(toObject(...fruits));
console.log(toObject2(...fruits));
console.log(toObject3(...fruits));
console.log(fruits[0], fruits[1], fruits[2]);

구조분해3.js

// 구조분해할당 - React(props) - Next.js(F/W) - FLUX아키텍쳐 -  상태관리해줌
// 객체다루기, 배열 다루기 (Handlebars - 템플릿)
// 데이셋(UI솔루션나오는 키워드:Set)을
//Oracle - 서블릿(컨트롤계층설계) - JSP(ejs, React, Vue.js,,,,) - POJO(1-1,1-2,1-3) - spring(레거시,Maven, Gradle)
// 데이터셋 누가 담당하나요? 백엔드 - Spring - Oracle, realtime firebase(채팅구현)

//html(ejs-입력받겠지)[WAS- views- 물리적위치-배포,배치-DevOps] -> 조회버튼 ->(자바)-> 오라클(select * from 도서) ->
//  ListKMap>[리턴타입] -> JSON(com.google.gson.Gson-  gson.jar)
// 자바스크립트(인터페이스:접점) - ajax, XMLHttpRequest, fetch()-비동기처리(콜백)
//fetch(a, b, ()=>{
//}).then((response)=>{JSON.springify(string-구조분해할당안됨) or parse(배열)})
//
// {} object -> [] Array-> [{},{},{}]((List<Map> or List<VO>))
const user = {
  name: '나신입',
  age: 35,
  email: 'nice@hot.com'
}

const user2 = {
  address:'서울시 마포구 공덕동',
  address2:'인천시'
}
console.log(user2);
const { address2 = '부산시' } = user2;
console.log(user2);
console.log(user2.address2);
console.log(address2);
const {name, age, email, address} = user;
console.log(name, age, email, address);
console.log(user.name);
console.log(user['name']);
console.log(`${user['name']}`);

클래스속성변경.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>클래스속성변경하기 - 실습</title>
  <link rel="stylesheet" href="클래스속성변경.css">
  <script src="클래스속성변경.js" defer></script>
</head>
<body>
  <ul class="list">
    <li><a href="#">메뉴1</a></li>
    <li><a href="#">메뉴2</a></li>
    <li><a href="#">메뉴3</a></li>
    <li><a href="#">메뉴4</a></li>
    <li><a href="#">메뉴5</a></li>
  </ul>
</body>
</html>

클래스속성변경.css

* {
  margin: 0px;
  box-sizing: border-box;
}

li {
  list-style: none;
}

a {
  text-decoration: none;
}

body {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

body .list {
  display: flex;
}

body .list li {
  width: 150px;
  height: 50px;
  border: 1px solid #aaaaaa;
}

body .list li a {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font: bold 16px/1 "arial";
  color: #777777
}

body .list li.on a {
  background-color: #777777;
  color: aqua;
}

클래스속성변경.js

const btns = document.querySelectorAll('.list li');
console.log(btns);

btns.forEach((btn,index) => {
  btn.addEventListener('click', (e)=> {
    for(let item of btns){
      item.classList.remove('on');
    }
    btns[index].classList.add('on');
  })
})

카카오도서api

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();
    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번 에러 발생
    대안으로 템플릿엔진을 지원하게 되었다
 -->

bookList.ejs

<div class="row mt-5 justify-content-end">
  <div class="col-6 col-md-4">
    <form name="frm">
      <div class="input-group">
        <input type="text" name="query" class="form-control" value="자바" />
        <button class="btn btn-danger">검색</button>
      </div>
    </form>
  </div>
</div>
<hr />
<!-- 카카오 도서검색 결과를 출력할 공간 마련하기 -->
<div class="row" id="list_book"></div>
<!-- 카카오 도서검색 결과를 출력할 공간 마련하기 -->
<!-- Handlebars Helper 추가 -->
<script>
  //가격 포맷형식 적용하기 - 3자리에 콤마 처리 - 정규표현식
  Handlebars.registerHelper('format', function (price) {
    return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '원';
  });
  //thumbnail이 없을 때 더미이미지로 대체하기
  Handlebars.registerHelper('image', function (thum) {
    if (thum) return thum;
    else return 'https://via.placeholder.com/120x174';
  });
</script>
<!-- Handlebars Helper 추가 -->

<!-- list_book안에 들어갈 템플릿 작성하기 -->
<script id="temp_book" type="text/x-handlebars-template">
  {{#each documents}}
    <div class='col-6 col-md-4 col-lg-2'>
      <div class='card my-2'>
        <div class='card-body'>
          <img
            src='{{image thumbnail}}'
            index='{{@index}}'
            alt='도서이미지'
            style='cursor: pointer;width: 80%;'
          />
          <div class='mt-2'>
            {{title}}
          </div>
        </div>
        <div class='card-footer' style='font-size:0.6rem;'>
          <div class='text-center'>
            {{format price}}
            <span
              class='cart ms-3'
              style='cursor:pointer;color:green'
            >CART</span>
          </div>
        </div>
      </div>
    </div>
  {{/each}}
</script>

<div class="text-center mt-2">
  <button class="btn btn-primary btn-sm px-5" id="prev">이전</button>
  <span id="page" class="px-3">1/10</span>
  <button class="btn btn-primary btn-sm px-5" id="next">다음</button>
</div>
<script>
  //사용자가 입력한 키워드 가져오기
  let query = $(frm.query).val();
  let page = 1;

  //DOM에 대한 접근을 jquery이용함 - jquery-1.12.0.js
  //document.getElementById('m_id') -> $('#m_id') or $('.m_id') or $('frm')
  //jquery - 표준은 아니다 - 표준은 바뀌지 않음,  다른 라이브러리가 나와도 호환됨
  // 브라우저에 따라 동작이 안될 수 도 있어서.... - 크로스브라우징서비스 -jquery
  //이벤트처리
  //이벤트 핸들러방법 - 마지막것만 적용됨
  //내장함수 - 매번 처리됨 - 이벤트 핸들러 이름에서 on만 떼고 쓴다
  // - e.target, or e.currentTarget - 정보(힌트)취득할때
  //submit -새로고침 - 신입 - e.preventDefault()
  //다음 버튼을 눌렀을 때 - page을 1씩 증가시킴
  $('#next').on('click', () => {
    page++;
    bookList();
  });
  //이전 버튼을 눌렀을 때 - page를 1씩 감소시킴
  $('#prev').on('click', () => {
    page--;
    bookList();
  });

  //도서 이미지를 클릭했을 때 도서 식별자 가져오기
  $('#list_book').on('click', '.card img', () => {
    //아래 this는 누구인가요? <img index=1>
    let index = $(this).attr('index');
    console.log(`사용자가 선택한 이미지 index값은 ${index}`);
  });

  const bookList = () => {
    console.log(`page=${page}, query=${query}`);
    $.ajax({
      type: 'get',
      url: 'https://dapi.kakao.com/v3/search/book?target=title',
      headers: { Authorization: 'KakaoAK 4b140cf1d4428a43b2d0318382e7b264' },
      data: { query: query, page: page, size: 20 },
      dataType: 'json',
      success: function (data) {
        console.log(data); //[object Object] ->JSON.stringify()
        //핸들바스 템플릿을 가져옵니다.
        const temp = Handlebars.compile($('#temp_book').html());
        //위에서 읽어온 템플릿(반복문적용된)결과를 div태그 내부에 끼워넣기 - 껍데기만 있으니까
        $('#list_book').html(temp(data));
        //핸들바스 템플릿에 바인딩될 데이터셋 입니다 - Array
        //너 마지막 페이지야?
        let is_end = data.meta.is_end;
        console.log(`너 마지막 페이지야? ${is_end}`);
        let total = data.meta.total_count;
        console.log(`검색결과의 총 레코드 수 ${total}`);
        //총페이지 수 - total/perpage
        //마지막페이지 수
        let last = Math.ceil(total / 20); //
        //바뀐 페이지 번호는 어떻게 구하지?
        $('#page').text(`${page}/${last}`);
        //너 첫번째 페이지야?
        if (page === 1) $('#prev').attr('disabled', true);
        else $('#prev').attr('disabled', false);
        //혹시 마지막 페이지인거야?
        if (is_end) $('#next').attr('disabled', true);
        else $('#next').attr('disabled', false);
      },
      error: function (error) {
        console.log(error); //디버깅시 힌트를 얻기위해서
      },
    }); // end of 비동기통신 처리
  }; ///// end of bookList()
  bookList();
  //submit 새로고침 방어하기
  $(frm).on('submit', (e) => {
    e.preventDefault();
    query = $(frm.query).val(); //val()는 jquery가 제공하는 함수임
    page = 1;
    bookList();
  });
</script>

routes-index.js

0개의 댓글