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 메서드에 추가해준다.
이렇게 하면 두 번째 요구사항도 구현 완료!
-참고 인프런 김정환 "만들고 비교하며 학습하는 리액트"