변화에 잘 대응하는 견고한 코드 작성을 목표로 했으니 실제로 변경 요청이 있을 때 본인이 작성한 코드가 변화를 잘 받아들일 수 있는지 검증해야 한다. 실무에서 으레 있을 법한 상황을 토대로 시나리오를 구성해봤다. Show 1-7-1 변화 상황 시나리오기본 자동검색은 보통은 아래와 같은 view를 제공한다. 그런데 이 검색 자동 완성 코드를 영화검색에 쓴다고 하는데, 영화검색에서 요구하는 결과 화면이 기존 검색완성 과는 다르다 어떻게 대응해야 하는가?1-7-2 변화 상황에 대응하기코드의 재사용 가능성?시나리오를 확인해보니 기본적인 기능(검색어 입력, 검색결과 네이비게이션 등)은 똑같지만 검색결과(resultView) 화면이 다르다. 그렇다면 전달받은 데이터소스를 처리하는 함수와, 처리된 데이터를 통해 화면을 그리는 템플릿 함수만 변화하면 기존에 사용했던 코드를 재사용 할 수 있다. 변화하는 내용을 config.js 내부에 resultView 객체에 있는 함수들을 변경 하면 된다. 변화를 예상하고 격리시켜 놨기 때문에 해당 변경은 다른 객체에 영향을 주지 않는다. 코드를 안심하고 변경할 수 있다. 실제 바꿔야하는 코드아래 코드에서 템플릿 함수 ( 0 , 1) 와 데이터 처리 ( 2) 만 바꿔주면 나머지 코드는 그대로 재사용이 가능하다. 목표달성이다. 짝짝짝!!
2. 고급 UI 제어* Debounce 및 Throttle 이해를 위한 참고자료
2-1. Debounce(사용자 입력시)2-1-1. 문제되는 상황
사용자가 특정 문자열을 입력할 때마다 매번 5 함수가 발동된다. 여기서 매번이 문제가 된다. 사용자는 본래 의도한 특정 문자열을 완성시키기 위해 연속적으로 키보드 입력을 한다. 입력이 연속적으로 들어온다는 것은 사용자가 자신의 의도를 아직 다 표현하지 않았음을 의미한다. 사용자가 의도한 문자열 입력을 완료하지 않은 상태에서 굳이 자동완성 결과를 매번 보여줄 필요가 없으며 이는 리소스 낭비일 수 있다. (아래 화면을 보면 입력시마다 5 함수가 실행되어 자동완성 목록이 업로드 된다.)2-1-2. Debounce 를 통한 해결사용자가 입력을 모두 마쳤을 때 5 가 한번만 발동되도록 하고, 연속적인 입력이 들어오면 아직 입력을 마치지 않은것으로 간주하여 함수 실행을 지연시키면 많은 리소스를 절약할 수 있다. 이런 전력을 취해 할 수 있는 UI 제어기법이 3 이다
debounce의 로직은 아래와 같다.
디바운스 적용을 한 결과는 아래와 같다. 같이 최종적으로 입력이 완료될 때 까지 자동완성이 보이지 않다가, 모든 입력이 완료된 이후에 한번만 자동완성 결과를 보여준다. 이렇게 하면 매번 callback을 실행하지 않아 리소스를 절약할 수 있다. 2-1-3. debounce 적용 before, after실제 화면으로 보니 예상대로 잘 동작한다. 짝짝짝!!! before - 입력시 마다 매번 const global = {
inputEl: '.autoComplete_input',
resultEl: '.autoComplete_result',
resultItem: 'autoComplete_result_item',
resultItemHighlighted: 'autoComplete_result_item-highlighted'
};
export const model = {
srcUrl: './src/data.json'
};
export const controller = {
inputEl: global.inputEl,
resultEl: global.resultEl,
resultItem: global.resultItem,
resultItemHighlighted: global.resultItemHighlighted,
debounceDelay: 300
};
export const inputView = {
inputEl: global.inputEl,
onSelect: 'onSelect',
throttleDelay: 60
};
export const resultView = {
resultEl: global.resultEl,
resultItem: global.resultItem,
resultItemHighlighted: global.resultItemHighlighted,
// 잦은 변경이 예상되는 템플릿 함수들
noResultSuggestionTemplate() {
//...
},
noResultRecentQueryTemplate() {
//...
},
recentQueryTemplate(recentQueryList) {
//...
},
suggestionTemplate(query, suggesions) {
//....
},
// 잦은 변경이 예상되는 데이터 처리함수
getAutoSuggesionList({ dataSrc, query, config }) {
//...
},
};
|