티스토리 뷰

Programming/TDD

03-중간정리

류시명 2022. 1. 16. 23:40

인프런 김정환 님 견고한 JS 소프트웨어 만들기 강의 노트 입니다.

1. 모듈 이용해서 화면 만들기

화면에 붙여보자

git checkout --force index.html-1

index.html

<html>
  <body>
    <span id="counter-display"></span>
    <button id="btn-increase">Increase</button>

    <script src="ClickCounter.js"></script>
    <script src="ClickCountView.js"></script>
    <script>
      // 즉시실행함수
      (() => {
        const clickCounter = App.ClickCounter();
        const updateEl = document.querySelector('#counter-display');
        const triggerEl = document.querySelector('#btn-increase');
        const view = App.ClickCountView(clickCounter, { updateEl, triggerEl });
        view.updateView();
      })()
    </script>
  </body>
</html>

2. 개선된 점

before

<button onclick="counter++; countDisplay()">증가</button>
<span id="counter-display">0</span>
<script>
  // 전역변수는 되도록 만들지 않는다.
  var counter = 0;
  // 재사용이 불가능함. 왜? counter-display라는 id로 하드코딩되어있기 때문임
  function countDisplay() {
    var el = document.getElementById('counter-display');
    el.innerHTML = counter;
  }
</script>

버튼 안에는 관심사가 혼재되어 있다.

버튼 태그 출력, counter값 증가시키고, countDisplay 함수 호출

index.html

<html>
  <body>
    <span id="counter-display"></span>
    <!-- 버튼만 출력함 -->
    <button id="btn-increase">Increase</button>

    <script src="ClickCounter.js"></script>
    <script src="ClickCountView.js"></script>

    <script>
      (() => {
        const clickCounter = App.ClickCounter();
        const updateEl = document.querySelector('#counter-display');
        const triggerEl = document.querySelector('#btn-increase');
        const view = App.ClickCountView(clickCounter, { updateEl, triggerEl });
        // 화면을 갱신함 
        view.updateView();
      })()
    </script>
  </body>
</html>

ClickCounter.js

var App = App || {}

// 데이터 관련한 건 여기에 모여있음
App.ClickCounter = () => {
  // counter라는 전역변수 대신 지역변수 사용
  // 이 value라는 데이터를 조회하거나 변경하려면 이 객체를 이용해야만 함. 외부에서는 접근 불가
  let value = 0

  return {
    // 다른 함수에서 호출하면서 closure를 이용함
    getValue() {
      return value
    },

    // 클릭 카운터 객체가 value를 증가시킴
    increase() {
      value++
    }
  }
}

ClickCountView.js


var App = App || {}

App.ClickCountView = (clickCounter, options) => {
  if (!clickCounter) throw new Error(App.ClickCountView.messages.noClickCounter)
  if (!options.updateEl) throw new Error(App.ClickCountView.messages.noUpdateEl)
  if (!options.triggerEl) throw new Error(App.ClickCountView.messages.noTriggerEl)

  const view = {
    // updateEl라는 인자를 받아서 innerHTML을 변경해줌
    updateView() {
      options.updateEl.innerHTML = clickCounter.getValue()
    },

    increaseAndUpdateView() {
      clickCounter.increase()
      this.updateView()
    }
  }
  // 버튼클릭이벤트를 여기서 바인딩함
  options.triggerEl.addEventListener('click', () => {
   view.increaseAndUpdateView()   
  })

  return view
}

App.ClickCountView.messages = {
  noClickCounter: 'clickCount를 주입해야 합니다',
  noUpdateEl: 'updateEl를 주입해야 합니다',
  noTriggerEl: 'triggerEl를 주입해야 합니다'
}
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함