Javascript

[js] mvc 패턴을 연습해보자 -4 추천검색어

popeyes 2023. 7. 20. 18:37

추천 검색어 구현

● 번호, 추천 검색어 이름이 목록 형태로 탭 아래 위치한다

● 목록에서 검색어를 클릭하면 선택된 검색어의 검색 결과 화면으로 이동한다

KeywordListView.js 파일을 만들어주고 초기 셋팅을 해준다.

 

export default class KeywordListView extends View {
constructor() {
super(qs("#keyword-list-view"));

this.template = new Template();
}

show(data = []) {
this.element.innerHTML =
data.length > 0
? this.template.getList(data)
: this.template.getEmptyMessage();
super.show();
}
}

 

 

템플릿 클래스에는

 

class Template {
getEmptyMessage() {
return `<div class="empty-box">추천 검색어가 없습니다</div>`
}

getList(data=[]) {
return `
<ul class="list">
${data.map(this._getItem).join("")}
</ul>
`
}

_getItem({id, keyword}) {
return `
<li data-keyword="${keyword}">
<span class="number">${id}</span>
${keyword}
</li>
`
}
}

지금까지 해온 로직과 비슷하다.

 

main.js 와 controller.js 파일에서도 이용할 수 있도록 셋팅한다.

 

아래는 main.js 파일 중 일부

function main() {
console.log(tag, 'main');

const store = new Store(storage);

const views = {
SearchFormView: new SearchFormView(),
searchResultView: new SearchResultView(),
tabView: new TabView(),
keywordListView: new KeywordListView(),
};

new Controller(store, views);
}

 

아래는 controller.js 파일 중 일부

 
export default class Controller {
constructor(store, { SearchFormView, searchResultView, tabView, keywordListView }) {
console.log(tag);

this.store = store;

this.SearchFormView = SearchFormView;
this.searchResultView = searchResultView;
this.tabView = tabView;
this.keywordListView = keywordListView;


this.subscribeViewEvents();
this.render();
}

 

추천 검색어는 화면을 그려주는 역할에서 담당해야 하기 때문에

render 메서드에 로직을 추가해보자

 

render() {
if (this.store.searchKeyword.length > 0) {
return this.renderSearchResult();
}

this.tabView.show(this.store.selectedTab);
if(this.store.selectedTab === TabType.KEYWORD) {
this.keywordListView.show(this.store.getKeywordList());
} else if (this.store.selectedTab === TabType.HISTORY) {
this.keywordListView.hide();
} else {
throw "사용할 수 없는 탭입니다.";
}

this.searchResultView.hide();
}

이렇게 첫 번째 요구사항인 

● 번호, 추천 검색어 이름이 목록 형태로 탭 아래 위치한다

완료!

 

다음은 두 번째 요구사항인

● 목록에서 검색어를 클릭하면 선택된 검색어의 검색 결과 화면으로 이동한다

를 구현해보겠다.

 

"이벤트를 처리하는 것은 view의 역할이다."

 

KeywordLIstView.js 로 가보자.

 

constructor에 this.bindEvent를 추가해준다.

bindEvent() {
delegate(this.element, "click", "li", event => this.handleClick(event))
}

 

handleClick(event) {
console.log(tag, "handleClick", event.target.dataset.keyword);
const value = event.target.dataset.keyword;
this.emit("@click", {value}); //검색결과는 본인의 역할이 아니기에 외부로 위임 - 커스텀이벤트 방식으로
}

이를 관리하는 controller.js 로 가서 

 

this.keywordListView.on('@click', event => this.search(event.detail.value));

컨트롤러가 실행이 되었을 때 바로 실행되는 subscribeViewEvent 메서드에 추가해준다.

 

이렇게 하면 두 번째 요구사항도 구현 완료! 

 

-참고 인프런 김정환 "만들고 비교하며 학습하는 리액트"