본문 바로가기
JavaScript/Vanila

[Vanila js] 검색 기능 구현하기

by D.O.T 2024. 7. 31.

Branch - ready/search-form-1

앞선 포스팅의 작업이 제대로 되었다면 main 브랜치에서

1. git checkout -b ready/search-form-1

2. 코드 작성

3. git add .

4. git commit -m "feat: 내용"

5. git push origin ready/search-form-1

PR

이후 PR 날리고 Rebase Merge 하기.

git bash에서 코드로 할 수도 있지만, 협업 중 코드 리뷰를 하는 과정이 있음.

그래서 직접 github 사이트에서 Merge하는 것에 익숙해지기

 

앞으로 모든 작업은 위 과정을 반복해서 branch를 업데이트 할 예정

 

 

// index.html
<script type="module" src="./js/main.js"></script>
    
// main.js
document.addEventListener("DOMContentLoaded", main);

function main() {}
  1. 정적페이지에 module로 main.js가 추가된 것을 알 수 있다.
    즉, main의 코드는 맨 처음 index.html을 DOM에서 불러올 때, main.js에 작성된 코드들을 모두 불러온다.
  2. main.js 에서 dom이 load될 때, main method를 eventListener로 추가한다.
  3. closer 개념으로 main method는 하나의 instance가 되고 main method에서 작성된 코드에 계속해서 접근할 수 있다.

즉, 뭐 작성할 코드가 있으면 main method에서 처리하면 된다.

강사님은 이것을 MVC 패턴을 활용해서 처리했다.

 

클로저의 자세한 설명: https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures

 

클로저 - JavaScript | MDN

클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합입니다. 즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다. JavaScript에서 클로저는 함수 생

developer.mozilla.org

 

export default class SearchFormView extends View {
    constructor() {
        super(qs("#search-form-view"));
        
        this.inputElement = qs("[type=text]", this.element);
        this.resetElement = qs("[type=reset]", this.element);

        this.showResetButton(false);
        this.bindEvents()
    }
}

View를 확장받는 검색 View를 살펴보자 

 

1. 정적페이지에 작성된 검색 폼 태그를 선택한다.

2. 해당 태그에 속해있는 녀석 중 type 속성이 text와 reset인 것을 가져온다.

3. 그리고 해당 태그들에 대한 기능들을 작성한다. -> 기능별로 잘 분리된 코드

 

    bindEvents() {
        on(this.inputElement, "keyup", () => this.handleKeyup());
        on(this.element, "submit", event => this.handleSubmit(event));
        on(this.resetElement, "click", () => this.handleReset());
    }

    handleSubmit(event) {
        event.preventDefault();

        const {value} = this.inputElement;
        this.emit("@submit", {value});
    }

이런식으로 각 메서드에 대한 event를 helper.js에서 utility로 구현한 on 메소드로 이벤트를 감지하고 핸들러 작업을 한다.

기본적으로 HTML에는 특정 이벤트에 대한 작업이 되어있다. 추가적인 작업이나 기존 작업을 없앨 경우, 핸들러를 사용해야한다.

 

emit 또한, helper.js에서 구현된 utility이다.

새로운 이벤트를 만들어서 전달한다.

 

export default class Controller {
  constructor(store, {searchFormView}) {
    this.store = store;
    
    this.searchFormView = searchFormView;

    this.subscribeViewEvents();
  }

  subscribeViewEvents() {
    this.searchFormView
    .on('@submit', (event) => this.search(event.detail.value))
    .on('@reset', () => this.reset());
  }
}

View에서 전달된 작업은 Controller에서 Catch하여 상세 작업을 한다.

궁금한 점

1. Controller에서 Business Logic을 작성할까?

2. Model에서 Business Logic을 작성하고 Controller에서 store 객체를 이용해 서비스 작업을 할까?

3. 그 다음 작업이 끝난 뒤 반환할 때는 View에게 다시 Event를 주는걸까? 

4. Controller에서 변화된 렌더링 작업을 할까?


퀘스트

검색어 Reset 버튼 클릭 시, 검색 내용 제거 및 검색어 지우는 작업

// View

    bindEvents() {
        on(this.resetElement, "click", () => this.handleReset());
    }
    
    
    handleReset() {
        this.emit("@reset");
        this.showResetButton(false);
    }
    
 // Controller
 
  subscribeViewEvents() {
    this.searchFormView
    .on('@reset', () => this.reset());
  }
  
  reset() {
    console.log("reset");
  }

 

1. input tag의 속성인 reset type은 HTML에서 제공하는 form data를 모두 지운다.

-> 그래서 따로 지우는 작업을 하지 않아도 된다.

2. 이후 검색 내용을 지우기 위해서 Controller에서 작업이 발생할테니까, 이벤트를 핸들러로 바인딩해두었다.

3. 바인딩된 핸들러 이벤트는 Controller에서 작업이 진행된다.

4. 작업이 끝나면 View 단에서 보여진 Btn을 숨기기위해 showResetButton 메소드를 실행한다.

 

    handleKeyup() {
        const {value} = this.inputElement;

        if (value.length <= 0) this.handleReset();
    }

강사는 검색내용을 작성하다 지울 때도 Reset을 하도록 했다.

'JavaScript > Vanila' 카테고리의 다른 글

[Vanila js] 탭 구현하기  (0) 2024.08.01
[Vanila js] 검색 결과 기능 구현  (0) 2024.07.31
[Vanila.js] 사전 코드 이해하기  (0) 2024.07.31
[Vanila.js] 환경셋팅 1  (0) 2024.07.30
[Vanila.js] 환경셋팅2  (0) 2024.07.30