[Javascript] Kendo UI 로컬스토리지 적용 방법

로컬 스토리지는 key : value 쌍으로 이루어져 있는 데이터 이며, Value는 JSON 형태를 이루고 있는 문자열 이여야 한다.

스토리지를 사용할 때 로컬 스토리지와 세션 스토리지를 사용하는데 로컬 스토리지는 웹브라우저를 닫아 세션이 끊겨도 데이터가 영구적으로 보관된다. 그래서 중요한 데이터는 저장하지 않는다.

 

로컬 스토리지와 세션 스토리지의 데이터를 보려면 개발자 도구 -> Application에서 확인 할 수 있다.

 

[로컬 스토리지 적용 이유]

회사에서 로컬스토리지를 이용한 이유는 리스트에서 열을 이동하고 검색을 하거나 다시 리스트를 불러 올때도 열이 이동된 상태로 유지되게 해달라는 요청 때문이였다.

 

먼저 위와 같이 Status 열을 오른쪽으로 옮길수 있어야 되는데 이 옵션은 reorderable이고 값이 true 여야 한다.

참고 : https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/reorderable

 

 

열을 유지되게 할수 있는 방법으로는 두가지 방법이 있다. 

첫번째는 저 kendo ui 로 만든 리스트를 파괴 시키고 다시 만들지 않고 데이터만 재로딩 시키는 방법이 있고,

두번째는 로컬스토리지에 열 순서를 저장하여 리스트를 불러들일때마다 로컬스토리지에 있는 열 순서로 바꾸는 방법이다.

 

첫번째가 월등히 쉽지만 레거시 소스여서 전 작업자가 무조건 파괴시키고 다시 만드는 방법을 택했는데 이 방법을 굳이 택한 이유를 알 수 없었다 그래서 두번째 방법을 택할 수 밖에 없었다.

 

[적용 방법]

열을 이동 시키면 실행되는 함수가 있는데 그게 columReorder() 함수이다.

참고 : https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/events/columnreorder

 

그래서 열을 옮기고 난 후 columnReorder() 함수에서 로컬스토리지에 열 순서 데이터를 담았다.

columnReorder: function(_e) {
        _e.preventDefault();

        const promise = new Promise(function(resolve, reject) {
            _e.sender.refresh();
            resolve();
        });

        //그리드의 dataBound함수가 실행된 후에 로컬스토리지에 옵션을 담기 위해서 동기 처리함
        promise.then(function() {
            _setGridOptionsToLocalStorage();
        });
}

function _setGridOptionsToLocalStorage() {
    var _options =  ui.container.list.data("kendoGrid").getOptions();

    if(_options) {
        switch(ui.config.id.menu){
            //Reseravtion탭의 Multi List화면
            case '1010':
                localStorage[ui.localStorage.reservationListName] = kendo.stringify(_options);
                break;
            //Front탭의 Multi List 화면
            case '1016':
                localStorage[ui.localStorage.frontListName] = kendo.stringify(_options);
                break;
            //HK탭의 Multi List 화면
            case '1028':
                localStorage[ui.localStorage.HKListName] = kendo.stringify(_options);
                break;
        }
    }
}

문제는 열을 옮기고 난 후의 열 순서의 데이터를 담아야 하는데 refresh() 함수를 통해 데이터가 적용되기전에 열 순서의 데이터를 가져오는 문제가 있어 promise를 통해 동기처리를 하였다. async, await 방법도 있었지만 이상하게도 이클립스에서 에러 메시지가 나와서 promise를 선택했다.

 

getOptions() 함수로 변경된 열 순서의 데이터를 가져오고 그 데이터를 stringfy() 함수를 통해 JSON 문자열 형태로 만들어줘서 로컬스토리지에 담는다. 그리고 f12 개발자 도구 -> Application 탭에서 저장된 로컬스토리지를 확인한다.

 

그리고 옮긴 열을 적용시키는데 문제가 있었다. getOptions() 함수로 그리드의 options을 가져온걸 그대로 적용시키는 setOptions() 함수가 있는데 이걸로 하면 리스트의 데이터 template 양식이 안먹는 오류가 있었다. stringfy() 함수가 문자열 형태로 바뀌는것이기 때문에 template function이 돌아가질 않는 것이다. 

 

예를 들어 db에서 가져온 값은 1,2,3,4 인데 이걸 다른 양식으로 보여주는 것이다.

template: function(_dataItem) {
        switch("" + (_dataItem.guestVip || "")) {
            case "1": return "VIP 1";
            case "2": return "VIP 2";
            case "3": return "VIP 3";
            case "4": return "VIP 4";
            default: return "";
        }
}

 

 

그래서 열순서를 직접 바꿔주는 reorderColumn()함수를 이용했다. 

/* 로컬 스토리지에 있는 컬럼순서 적용 하는 함수 */
function _applyColumnOrderByLocalStorage(_e) {
    var _options = null;

    switch(ui.config.id.menu){
        //Reseravtion탭의 Multi List화면
        case '1010':
            _options = localStorage.getItem(ui.localStorage.reservationListName);
            break;
        //Front탭의 Multi List 화면
        case '1016':
            _options = localStorage.getItem(ui.localStorage.frontListName);
            break;
        //HK탭의 Multi List 화면
        case '1028':
            _options = localStorage.getItem(ui.localStorage.HKListName);
            break;
    }

    if(_options) {
        var _optionsColumns = JSON.parse(_options).columns;

        for(var i = 0; i < _optionsColumns.length; i++) {
            var _field = _optionsColumns[i].field;

            $.each(_e.sender.columns, function(_idx, _el) {
                if(_field == _el.field) {
                    _e.sender.reorderColumn(i, _el);
                }
            })
        }
    }
}

 

데이터 적용 시점은 데이터가 바인딩되는  dataBinding 시점에서 하였다.

dataBinding: function(_e) {
        _applyColumnOrderByLocalStorage(_e);
},

 

로컬스토리지 삭제시점은 새로고침을 눌렀을때만 이여서 세션스토리지 보다는 로컬스토리지를 사용하였고, 삭제는 remove() 함수를 이용한다.

function _removeLocalstorage() {
    switch(ui.config.id.menu){
        //Reseravtion탭의 Multi List화면
        case '1010':
            localStorage.removeItem(ui.localStorage.reservationListName);
            break;
        //Front탭의 Multi List 화면
        case '1016':
            localStorage.removeItem(ui.localStorage.frontListName);
            break;
        //HK탭의 Multi List 화면
        case '1028':
            localStorage.removeItem(ui.localStorage.HKListName);
            break;
    }
}

댓글

Designed by JB FACTORY