SMART datagrid v1.4 > Concepts
SMART datagrid는 사용자 입력이나 데이터셋 수정을 단계별로 되돌리거나(Undo), 다시실행(Redo)할 수 있는 옵션을 제공한다. 데이터 수정은 그리드와 데이터셋 수준에서 발생할 수 있는데, 그리드에서는 사용자가 행을 수정, 추가할 때 발생하고, 데이터셋 수정은 그리드에서 편집 완료된 데이터가 데이터셋에 전달되거나, 데이터셋 Api 메소드들을 직접 호출할 때 발생한다.
그리드 행 편집 중 Undo/Redo를 가능하게 하려면 GridBase.undoable를 true로 지정한다. 또, 데이터셋 내에서 Undo/Redo를 가능하게 하려면 DataSet.undoable를 true로 지정한다. 대개의 경우 사용자에게 Undo/Redo UI를 제공할 때 두 속성을 모두 true롤 지정하면 된다. 실행 중에 undoable 속성을 변경하거나, DataSet.clearUndo, GridBase.clearUndo를 호출하면 Undo 스택이 비워지고 Undo 이력이 새로 시작하게 된다.
dataset.setUndoable(true);
grid.setUndoable(true);
Undo/Redo가 가능해지면, 사용자는 실행 시간에 표준 입력키인 Ctrl+Z과 Ctrl+Y를 입력해서 각각 Undo와 Redo를 실행할 수 있다. 스크립트에서는 GridBase.undo, redo 함수를 호출해서 Undo, Redo를 실행한다. 또, 현재 Undo, Redo가 각각 실행가능한 상태인 지는 각각 GridBase.canUndo, canRedo 호출로 알 수 있다. canUndo, canRedo 상태가 변경되면 onUndoStateChanged 이벤트가 발생한다.
grid.onUndoStateChanged = function (grid, canUndo, canRedo) {
document.getElementById("btnUndo").disabled = !canUndo;
document.getElementById("btnRedo").disabled = !canRedo;
};
$("#btnUndo").click = function () {
grid.undo();
};
$("#btnReco").click = function () {
grid.redo();
};
Undo 리스트와 Redo 리스트를 유지하는 방식은 일반적인 문서 어플리케에션에 처리하는 것과 유사하다. 각각의 변경 호출이 Undo 스택에 추가되고, Undo가 호출되면 다음 Undo 위치가 이전 변경 호출로 이동한다. Undo 스택 바닥까지 이동하면 canUndo가 false가 된다. Redo 호출은 Undo와 반대 방향으로 이동해서 가장 최근의 변경 호출 시점까지 다시 실행한다. 또, Undo 스택의 중간 지점에서 Redo를 하지 않고 새로운 변경 호출이 추가되면, 그 지점 부터 가장 최근까지 스택에 보관된 Redo 호출들은 제거된다.
데이터셋이 undoable이면, 데이터셋을 변경하는 공식적인 그리드 데이터셋과 트리 데이터셋의 모든 메소드들은 데이터셋의 Undo 스택에서 관리된다. 즉, 데이터셋 변경을 되돌릴 수 있고, 다시 실행할 수 있게 된다. 실행 시간 사용자는 Ctrl+Z, Ctrl+Y 키를 사용할 수 있고, undo, redo 메소드를 직접 호출할 수도 있다.
아래 테이블에 두 데이터셋의 관리되는 메소드들이 나열되어 있다.
Method | UI | Description |
---|---|---|
clearRows | 기존 행들을 모두 삭제한다. | |
setRows | 기존 행들을 모두 제거하고, 새로운 행들을 추가한다. | |
setXmlRows | 기존 행들을 모두 제거하고, 새로운 행들을 Xml 원본으로 추가한다. | |
setRowCount | 데이터행 개수슬 변경한다. | |
setValue | 한 행, 한 필드의 값을 변경한다. | |
updateRow | 한 행의 값을 변경한다. | |
updateRows | 여러 행의 값을 동시에 변경한다. | |
updateXmlRows | 여러 행의 값을 동시에 Xml 원본으로 변경한다. | |
updateValues | 조건에 일치하는 행들의 값을 변경한다. | |
deleteRow | 한 행을 삭제한다. | |
deleteRows | 여러 행을 삭제한다. | |
insertRow | 한 행을 삽입한다. | |
appendRow | 한 행을 마지막에 추가한다. | |
insertRows | 여러 행을 삽입한다. | |
insertXmlRows | 여러 행을 Xml 원본으로 삽입한다. | |
appendRows | 여러 행을 마지막에 추가한다. | |
appendXmlRows | 여러 행을 마지막에 Xml 원본으로 추가한다. | |
moveRow | 한 행을 다른 위치로 이동시킨다. | |
moveRows | 여러 행을 동시에 다른 위치로 이동시킨다. | |
setRowState | 한 행의 상태를 강제로 변경시킨다. | |
setRowStates | 여러 행의 상태를 동시에 강제로 변경시킨다. | |
clearRowStates | 모든 행들의 상태를 초기화 한다. | |
restoreUpdatedStates | 수정된 행들의 상태를 복원시킨다. | |
restoreUpdatedRows | 수정된 행들의 값을 복원시킨다. | |
setRowTag | 한 행의 tag를 설정한다. | |
setRowTags | 여러 행의 tag를 설정한다. | |
unsetRowTags | 한 행 이상의 tag를 제거한다. | |
clearRowTags | 모든 행의 tag를 제거한다. |
Method | UI | Description |
---|---|---|
clearRows | 기존의 모든 행을 삭제한다. | |
setRows | 기존의 행들을 모두 제거하고 새로운 행들을 추가한다. | |
setXmlRows | 기존의 행들을 모두 제거하고 Xml 원본으로 새로운 행들을 추가한다. | |
setJsonRows | 기존의 행들을 모두 제거하고 Json 배열로 새로운 행들을 추가한다. | |
insertDataRows | 배열로 새로운 행들을 지정한 위치에 삽입한다. | |
insertJsonRows | Json 배열로 새로운 행들을 지정한 위치에 삽입한다. | |
insertXmlRows | Xml 원본으로 새로운 행들을 지정한 위치에 삽입한다. | |
appendDataRows | 배열로 새로운 행들을 마지막에 추가한다. | |
appendJsonRows | Json 배열로 새로운 행들을 마지막에 추가한다. | |
appendXmlRows | Xml 원본으로 새로운 행들을 마지막에 추가한다. | |
insertRow | 지정한 위치에 한 행을 삽입한다. | |
addRow | 마지막에 한 행을 추가한다. | |
insertRows | 지정한 위치에 여러 행을 삽입한다. | |
addRows | 마지막에 여러 행을 추가한다. | |
deleteRow | 한 행을 삭제한다. | |
deleteRows | 여러 행들을 동시에 삭제한다. | |
setValue | 한 행, 한 필드의 값을 수정한다. | |
updateRow | 한 행을 수정한다. | |
setRowTag | 한 행의 tag를 설정한다. | |
setRowTags | 여러 행의 tag를 동시에 설정한다. | |
unsetRowTags | 지정한 행들의 tag를 제거한다. | |
clearRowTags | 모든 행들의 tag를 제거한다. | |
setRowState | 한 행의 상태를 강제로 변경한다. | |
setRowStates | 여러 행의 상태를 강제로 변경한다. | |
clearRowStates | 모든 행의 상태를 초기화 한다. |
그리드의 undoable을 true로 지정하면 실행 시간 사용자가 행을 수정하거나 추가할 때, 셀 단위 편집 활동을 그리드 Undo 스택에서 관리하게 된다. 사용자는 Ctrl+Z 키와 Ctrl+Y 키로 각각 Undo 및 Redo할 수 있게 된다. 또, undo, redo를 직접 호출할 수도 있다. 일반적으로 아래와 같은 절차대로 진행된다.
데이터셋의 경우와 마찬가지로 그리드 Undo 스택에 변화가 생기면, onUndoStateChanged 이벤트가 발생한다. 이 이벤트 내에서 Undo, Redo 가능 여부를 알 수 있고, 직접 canUndo, canRedo를 통해서 알 수도 있다.
SMART datagrid가 기본으로 제공하는 사용자 인터페이스 외에 어플리케이션에서 필요한 특별한 UI를 구현할 때, 둘 이상의 데이터셋 메소드를 동시에 호출해서 사용자가 보기에는 하나의 호출처럼 여겨지도록 할 필요가 있다. 즉, Ctrl+Z, Ctrl+Y 키 입력 하나로 Undo, Redo가 되도록 해야 할 경우에, GroupAction을 사용할 수 있다.
아래 코드와 같이 GroupAction을 생성하고 실행하는 데는 두 가지 방법이 있다. 먼저 데이터셋으로 부터 GroupActio을 요청하고 리턴된 GroupAction에 실행할 메소드들을 추가한다. 그리고, 데이터셋에 GroupAciton의 실행을 요청하면 된다.
// 새로운 group action을 요청하고
var ga = ds.createActionGroup();
// 변경 작업들을 추가하고
ga.updateRow(0, values);
ga.deleteRows([1, 2]);
ga.insertRow(1, newValues[0]);
ga.insertRow(2, newValues[1]);
// 실행을 요청한다.
ds.execute(ga);
비슷하게, 데이터셋의 beginActions, endActions를 이용해서 구현할 수 있다. createActionGroup과 다른 점은 beginActions, endActions 사이에 내연적으로 리턴되는 GroupAction을 통하지 않고 해당 데이터셋의 다른 변경 메소드를 호출할 수 없다는 것이다.
// 새로운 group action을 요청하고
ds.beginActions();
// 변경 작업들을 추가하고
ds.updateRow(0, values);
ds.deleteRows([1, 2]);
ds.insertRow(1, newValues[0]);
ds.insertRow(2, newValues[1]);
// 실행을 요청한다.
ds.endActions();
주의할 점은, GroupAction이 DB의 트랜잭션과 같이 처리되지 않는다는 것이다. 즉, 그룹에 포함된 모든 변경 요청이 모두 실행되거나 모두 실패하는 것이 아니고, 실패가 발생하기 전까지는 실행 변경이 데이터셋에 반영되고, 그 시점까지의 이력이 데이터셋 스택에 보관된다.
사용자 데이터셀 편집 외에 선택 행들 삭제 및 선택 영역 값 지우기 또한 되돌릴 수 있다. 또, AutoFill 핸들을 이용한 데이터 편집도 되도릴 수 있다.
이런 일들은 모두 내부적으로 단위 편집 Action으로 정의되고, 단위 Action들이 Undo/Redo 스택을 통해 관리된다. DataSet의 데이터 수정 Api 함수들 또한 Action들로 관리된다.
대개의 경우 사용자 변경에 따라 호출되는 메소드들은 변경 실행전 확인 이벤트를 발생시키고, 변경 작업 후 완료 이벤트를 발생시킨다. 예륻 들어, GridDataSet.deleteRow는 행을 삭제하기 전에 onRowDeleting 이벤트를 발생시키는데, 이벤트 핸들러 내에서 명시적으로 Boolean false를 리턴하거나 예외를 발생시키면 삭제 작업이 중단된다. 또, 삭제 완료 후 onRowDeleted 이벤트를 발생시킨다.
DataSet이 undoable인 경우 고려해야 할 점은 연이어 실행되고 또 Undo/Redo되는 변경 메소드들의 흐름에서 데이터셋의 왜곡이 일어나지 않도록 하는 것이다. 또, 최대한 실행 이력을 보관하도록 한다. 이를 위해 SMART datagrid는 예외와 관련된 간명한 정책을 구현하고 있다.
위에서 설명한대로, 최종 사용자에게 GroupAction은 단위 활동이지만, 데이터셋 변경은 그룹에 포함된 요청 단위로 실행된다.
"문서를 오픈한 후에 편집이 시작된다"는 것이 일반적인 사용자 경험이므로, DataSet의 Undoable 상태는 가능한 최초 데이터셋을 로드한 후에 시작돼야 한다. 또, 경우에 따라서는 변경된 데이터셋을 서버 등에 업로드한 후에는, DataSet.clearUndo나 GridBase.clearUndo를 호출해서 Undo 스택을 비우고 새로 시작하는 것이 적당한 UI일 수 있다.
DataSet이 undoable 상태가 되면, 기본적으로 데이터셋의 값을 변경하는 모든 단위 호출 이력이 복원에 필요한 정보들과 함께 Undo 스택에 저장된다. 함수 호출에 사용된 매개변수들과 보관이 필요한 값들이 모두 포함된다. 따라서 사용자 인터페이스에서 불필요한 데이터까지 보관되지 않도록 주의해야 한다. 특히, 초기 데이터셋 로드 후에 undoable 가능하도록 해야 하고, 편집 데이터셋을 서버에 전송한 후에는 clearUndo로 스택을 초기화 해야 한다.