[]
        
(Showing Draft Content)

실행 취소 및 다시 실행

테이블 시트에서는 데이터에 대해 수행된 변경 작업을 Undo(실행 취소)Redo(다시 실행) 기능을 통해 되돌리거나 다시 적용할 수 있습니다.

이 페이지에서는 지원되는 작업의 범위, Undo/Redo 동작이 작동하는 구체적인 영역, 데이터 동기화와 관련된 중요한 고려 사항을 설명합니다.

지원되는 Undo 및 Redo 작업

테이블 시트의 Undo 및 Redo 기능은 다음을 포함한 다양한 즉각적인 작업을 지원합니다:

  • 구성 변경: 필터링, 정렬 등과 같은 설정 변경

  • 런타임 UI 작업: 워크시트와 유사한 셀 편집, 행/열 추가 및 제거, 데이터 붙여넣기, 행/열 드래그 및 이동 등

  • 테이블 시트 API: setDataView 를 제외한 대부분의 데이터나 설정 변경 API

    예: options, setDefaultRowHeight, rowActionOptions, togglePinnedRows, togglePinnedColumns, groupBy

    API는 워크시트 명령과 동일한 방식으로 Undo를 활성화하며, 명령을 필요에 따라 커스터마이즈할 수 있음

  • SpreadJS 디자이너 지원: SpreadJS 디자이너에서 대부분의 테이블 시트 작업에 대해 Undo/Redo 지원

    • TABLE SHEET DESIGN 리본 : 행 높이 조정, 행 높이 누적, 상태 규칙 관리, 테마 색상 서식 등 주요 테이블 시트 리본 탭 작업에 대해 실행 취소/다시 실행을 수행합니다.

      image


    • 테이블 시트 열 리본 : 열 구성과 관련된 실행 취소/다시 실행 작업을 수행합니다.


      image


    • 테이블 시트 디자인 모드: 테이블 시트 레이아웃을 구성할 때 실행 취소/다시 실행을 사용합니다.


      image


    • 실행 취소/다시 실행 목록: 실행 취소 및 다시 실행 작업 목록을 보고 관리할 수 있습니다. 목록에 있는 작업 항목을 클릭하면 해당 작업 단계로 되돌릴 수 있습니다.

      image

다른 작업에서 실행 취소(undo) 동작

다음 표는 서로 다른 동기화 모드에서의 작업별 실행 취소 동작을 보여줍니다:

작업

static

autoSync

batch

Add

  • 실행 취소 시 레코드가 삭제됨

  • 서버에 저장됨: 서버 및 로컬에서 레코드가 삭제됨

  • 서버에 저장되지 않음: 로컬에서 레코드가 삭제됨

  • 실행 취소 시 레코드가 삭제됨

  • 로컬에서 레코드가 삭제됨

Update

  • 실행 취소 시 데이터가 이전으로 복원됨

  • 서버에 저장됨: 실행 취소 시 상태가 dirty로 설정됨

  • 서버에 저장되지 않음: 실행 취소 시 상태가 normal로 설정됨

Delete

  • 실행 취소 시 레코드가 다시 추가됨

  • 상태는 added

  • 실행 취소 시 레코드가 다시 추가됨

  • 서버에 저장됨: 상태는 추가됨

  • 서버에 저장되지 않음: 상태는 normal

참고:

  • 데이터 원본 탭 구성은 실행 취소 및 다시 실행 기능을 지원하지 않습니다.

  • 특정 작업은 실행 취소 스택을 초기화하여 이전 변경 사항을 되돌릴 수 없게 만듭니다. 이러한 작업은 런타임 환경과 디자이너 모드에 따라 다릅니다.

    • 런타임에서:

      • setDataView API는 실행 취소 스택을 초기화합니다.

      • 서버에서 데이터를 다시 가져오는 작업은 실행 취소 스택을 초기화합니다.

      • tableSheet.reset()은 실행 취소 스택을 초기화합니다.

    • 디자이너에서:

      • 디자이너에서 테이블을 재설정하면 실행 취소 스택이 초기화됩니다.

      • 단, 테이블이 비어 있는 상태에서 설정될 경우 실행 취소 스택은 초기화되지 않습니다.

      • 데이터를 다시 가져오는 작업은 실행 취소 스택을 초기화합니다.


데이터 원본 변경에 대한 특별 고려 사항

각 실행 취소 동작은 로컬 데이터만 수정합니다. 단, autoSync 모드에서 행 추가에 대한 실행 취소는 예외입니다. 이 모드에서는 행을 삭제하면 서버와 바로 동기화되며, 실행 취소 시 해당 행이 목록의 마지막에 다시 추가됩니다.

또 다른 일반적인 방법은 삭제를 나타내는 플래그를 사용하는 것입니다. 이 방법은 보다 유연한 처리를 가능하게 합니다. 삭제된 열을 실행 취소로 복원하려면, 서버가 삭제 플래그를 통해 삭제를 표현할 수 있어야 합니다. 이러한 지원이 없다면, 삭제된 행은 프론트엔드에서 원래 위치로 복원되지만, 페이지나 데이터를 새로고침하면 해당 항목은 목록의 끝으로 이동하게 됩니다.

다음 코드는 삭제 플래그를 추가하는 간단한 예제를 보여줍니다. 코드를 실행하고 데이터를 변경한 후 Ctrl + Z를 눌러 실행 취소 동작을 확인해보세요.

Ask ChatGPT

  window.onload = function () {
      var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 0 });
      initSpreadJS(spread);
  };
  const jsonData = [
      {
          "Id": 1,
          "CompanyName": "Exotic Liquids",
          "ContactName": "Grace Campbell",
          "ContactTitle": "Purchasing Manager",
          "Address": "248 Jac And Mac St",
          "City": "Raven",
          "Region": "Southeast",
          "PostalCode": "24639",
          "State": "Virginia",
          "Phone": "(276) 964-4382",
          "Fax": null,
          "HomePage": null
      },
      {
          "Id": 2,
          "CompanyName": "New Orleans Delights",
          "ContactName": "Bert Garrett",
          "ContactTitle": "Order Administrator",
          "Address": "5291 Collins Rd",
          "City": "Middleburg",
          "Region": "Southeast",
          "PostalCode": "32068",
          "State": "Florida",
          "Phone": "(904) 264-9720",
          "Fax": null,
          "HomePage": null
      },
      {
          "Id": 3,
          "CompanyName": "Grandma Kellys Homestead",
          "ContactName": "Doris Schultz",
          "ContactTitle": "Sales Representative",
          "Address": "488 W Loyola Ave",
          "City": "Clovis",
          "Region": "West",
          "PostalCode": "93619",
          "State": "California",
          "Phone": "(559) 451-0210",
          "Fax": null,
          "HomePage": null
      },
      {
          "Id": 4,
          "CompanyName": "Tokyo Traders",
          "ContactName": "Judy Gill",
          "ContactTitle": "Marketing Manager",
          "Address": "664 N Holden St",
          "City": "Port Washington",
          "Region": "Midwest",
          "PostalCode": "53074",
          "State": "Wisconsin",
          "Phone": "(262) 284-5862",
          "Fax": null,
          "HomePage": null
      }
  ]

  function initSpreadJS(spread) {
      spread.suspendPaint();
      spread.clearSheets();
      spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader;
      // 데이터 매니저 초기화
      var dataManager = spread.dataManager();
      var myTable = dataManager.addTable("myTable", {
          autoSync: true, // autoSync 모드 활성  // 이는 데모를 위한 코드입니다. 실제 환경에서는 이러한 로직이 서버에서 구현되어야 합니다.
          remote: {
              read: async function () {
                  return jsonData.filter(item => item._isDelete !== true);
              },
              delete: async function (item) {
                  const sourceIndex = deleteItem(item[0]);
                  return jsonData[sourceIndex]
              },
              create: async function (changes) {
                  return createItem(changes);
              }
          }
      });
      function deleteItem(dataItem) {
          const sourceIndex = jsonData.findIndex(item => item.Id === dataItem.Id);
          jsonData[sourceIndex]._isDelete = true;
          return sourceIndex;
      }
      function createItem(dataItem) {
          const index = jsonData.findIndex(item => item.Id === dataItem.Id);
          if (index > -1 && jsonData[index]) {
              jsonData[index]._isDelete = false;
              return jsonData[index];
          } else {
              jsonData.push({ ...dataItem, Id: createID() });
              return jsonData[jsonData.length - 1];
          }
      }
      function createID() {
          return `${Math.random() * 1000}`;
      }

      // 테이블 시트 초기화
      const sheet = spread.addSheetTab(0, 'tablesheet', GC.Spread.Sheets.SheetType.tableSheet);
      var rowActions = GC.Spread.Sheets.TableSheet.BuiltInRowActions;
      var options = sheet.rowActionOptions();
      options.push(
          rowActions.removeRow,
          rowActions.saveRow,
          rowActions.resetRow,
      );
      sheet.rowActionOptions(options);

      // 테이블 시트에 뷰를 바인딩
      myTable.fetch().then(function () {
          const view = myTable.addView("myView", [
              { value: "Id", width: 50, caption: "Id" },
              { value: "CompanyName", width: 100, caption: "CompanyName" },
              { value: "ContactTitle", width: 100, caption: "ContactTitle" },
              { value: "Phone", width: 100, caption: "Phone" },
              { value: "State", width: 100, caption: "State" }
          ]);
          sheet.setDataView(view);
      });

      spread.resumePaint();
  }