본문 바로가기

Front-End

localstorage를 활용한 메뉴 History 저장

728x90

본 게시글은 재직 중인 증권사 MTS를 개발하면서 localstorage를 활용해 개인이 들어갔던 메뉴를 저장하고 불러오는 로직을 기록하기 위함입니다. 

 

자사 메뉴는 기본적으로 다음과 같은 구성으로 되어있습니다.(예시)

1)  주식

    1-1) 국내주식 현재가

    1-2) 국내주식 주문

      . 

      .

 

위 방식처럼 쭉 대분류, 중분류, 소분류로 메뉴가 이어지면 사용자 입장에서 필요한 기능은 다음과 같을 것입니다.

1) 검색기능

2) 최근 메뉴

3) 자주 찾는 메뉴

 

 

검색 기능은 다음에 기회가 되면 정리하도록 하고, 최근 메뉴와 자주찾는메뉴를 어떻게 구현했는지 소개하겠습니다.

 

최근메뉴

우선 자사 앱은 하이브리드 앱으로 네이티브 위에 웹뷰를 얹어 웹 개발 방식으로 개발되어 있습니다.

하이브리드 앱은 IOS, android 구분 없이 하나의 코드로 각 네이티브 언어에 맞게 빌드가 되어 개발이 편리하다는 장점이 있지만 완전히 네이티브의 기능을 다 활용할 수 없다는 단점이 있습니다. 하지만 cordova와 같은 브리지 역할을 해주는 플랫폼이 있어 이 마저도 보완이 되었습니다. 

 

즉, 웹 개발 방식으로 개발이 되었기 때문에 JS와 HTML로 개발을 할 수 있고 네이티브 저장공간뿐만 아니라

localstorage를 사용해서 각 사용자 브라우저에 정보를 저장해 개인 맞춤형 서비스를 제공할 수도 있습니다.

 

브라우저의 캐시를 삭제하지 않는 이상 localstorage에 저장해놓으면 DB를 사용하지 않고도 데이터를 저장하고 가져다가 쓸 수 있습니다.

 

function Menu*setMenuHistory(menuObj)
{
	this.menuHistory = JSON.parse(localStorage.getItem('MenuHistory')) || []; 
	//localstorage 에 저장된 정보가 없으면 빈 array로 초기화시켜줍니다.
	
	if(this.menuHistory){
		for(var i = 0; i<this.menuHistory.length;i++){
			if(this.menuHistory[i].name == menuObj.name){
				this.menuHistory.splice(i,1);
			}
		} // (2)
		
		if(this.menuHistory.length>9) {
			//오류로 10개 초과로 담길 수도 있기 때문에 10개 남을때까지 제거
			while(this.menuHistory.length>9){
				this.menuHistory.pop();		
			}
		}//(3)
	}
	this.menuHistory.unshift(menuObj); //(4)
	localStorage.setItem('MenuHistory', JSON.stringify(this.menuHistory));
};

 

setMenuHistory 함수는 사용자가 메뉴 항목을 터치할 때 해당 페이지로 이동함과 동시에 호출이 되는 함수입니다.

따라서 파라미터로 터치된 메뉴 항목 정보를 받아오죠

메뉴 항목 정보는 {"name" : "국내 주식 현재가"}와 같은 object 형태로 넘어옵니다.

 

만약 this.menuHistory 정보가 있다면(사용자가 이전에 한 번이라도 메뉴를 통해서 페이지 이동을 했다면) (2) 번과 같이 중복체크와 (3) 번과 같이 개수 체크를 합니다. 

 

*(2) 번 로직은 this.menuHistory를 탐색하면서 사용자가 누른 메뉴 항목이 이전에 눌렸었는지 체크합니다.

만약 있다면 this.menuHistory 에서 제거합니다. 제거하는 이유는 아래와 같습니다.

만약 this.menuHistory가 [{"name" : "국내 주식 현재가"}, {"name" : "국내주식 주문"}]  이런 값을 가지고 있다고 했을 때 사용자가 다시 한번 국내주식 주문이라는 메뉴로 이동한다면 해당 메뉴가 this.menuHistory 에서 빠져서
[{"name" : "국내 주식 현재가"] 만 남게 됩니다. 그 다음 (4)번에서 unshift 를 통해 this.menuHistory 는 [{"name" : "국내주식 주문"}, {"name" : "국내주식 현재가"}]처럼 순서가 바뀌게 됩니다. 이러면 "최근 메뉴"라는 기능을 구현할 수 있게 되죠.

 

*(3) 번 로직은 최근 메뉴를 10개만 가지고 있기 위해 개수를 체크하는 로직입니다.

 

 

자주 찾는 메뉴

자주 찾는 메뉴는 최근 메뉴처럼 localstorage를 활용하지만 저장할 때 count 값을 같이 저장해주어야 합니다. 

최근 메뉴에서는 [{"name" : "국내 주식 현재가"}, {"name" : "국내주식 주문"}]  와 같았다면 자주찾는 메뉴는

[{"name" : "국내주식 현재가", "count" : 1}, {"name" : "국내주식 주문", "count" : 2}]처럼 말이죠.

 

function Menu*setMenuRank(menuObj){
	this.menuRank = JSON.parse(localStorage.getItem('MenuRank')) || []; 
	
    //중복체크
	var isNew = true;
	var index;
	for(var i= 0; i<this.menuRank.length;i++){
		if(this.menuRank[i].name==menuObj.name) {
			isNew = false;
			index = i;
			break;
		}
	}//(1) 
	if(isNew){
		menuObj['count'] = 1;
		this.menuRank.push(menuObj);
	}else{
		this.menuRank[index]['count'] += 1;
	}//(2)
	
	localStorage.setItem('MenuRank', JSON.stringify(this.menuRank));
};

setMenuRank 또한 setMenuHistory 함수처럼 사용자가 메뉴 항목을 터치했을 때 페이지 이동과 동시에 호출되는 함수입니다.  역시 파라미터로 메뉴 정보를 받습니다.

 

*(1), (2)에서 사용자가 누른 메뉴가 this.menuRank 에 있는지 중복체크를 한 다음 있으면 count +1 해주고 없으면 count를 1로 초기화해줍니다.

 

최근 메뉴는 unshift를 통해 사용자가 누른 메뉴를 this.menuHistory 배열에 가장 앞에만 넣어주면 되지만 자주 찾는 메뉴는 count값 순서대로 정렬을 해주어야 합니다. 하지만 보시다시피 위 코드에서는 정렬해주는 로직이 없죠.

 

저는 localstorage에 저장해줄 때 말고 저장된 값을 get 해올 때 한 번만 정렬해주기로 했습니다.왜냐하면 사용자가 메뉴를 누를 때마다 정렬을 해주는 것보다 자주 찾는 메뉴(this.menuRank)를 localstorage에서 getItem 할 때 한 번만 정렬하는 게 더 깔끔했기 때문입니다.

 

따라서 getMenuRank 함수를 다음과 같이 구현했습니다.

function Menu*getMenuRank(){
	this.menuRank = JSON.parse(localStorage.getItem('MenuRank'));
	
	this.menuRank.sort((a,b) => b.count- a.count);
	return this.menuRank;
};

sort 함수를 이용해서 count값이 큰 순서대로 정렬을 해줍니다.

 

 


비교적 간단한 로직이지만 메뉴는 어떤 서비스에서든 사용하고 있기 때문에 에러 없이 깔끔하게 짜는 것이 중요합니다.

따라서 더 좋은 방법이 있거나 문제 되는 게 있으면 댓글 남겨주세요 :)