[]
        
(Showing Draft Content)

CRUD 작업

간트 시트는 Create, Read, Update, Delete(CRUD)를 포함한 행(row) 작업을 통해 사용자가 데이터와 상호작용할 수 있도록 합니다.

이러한 작업은 편리하게 수정된 행 데이터를 데이터베이스와 동기화할 수 있도록 합니다.

다음은 행 작업으로 사용할 수 있는 GanttSheet 클래스 메서드입니다:

메서드

설명

addRow

테이블에 새 행을 추가합니다.

removeRow

지정된 행을 테이블에서 제거합니다.

saveRow

수정되거나 삽입된 행을 포함하여 지정된 행의 변경 사항을 데이터 매니저에 저장합니다.

resetRow

지정된 행의 변경 사항을 초기화합니다.

간트 시트 메서드

다음 샘플 코드를 통해 간트 시트에서의 CRUD 작업을 이해해봅시다.

Create (작업 삽입)

간트 시트에 새로운 작업을 추가합니다.

여기에는 계층적 관계(예: 상위-하위 관계)도 포함됩니다. 작업은 배치 모드로 큐에 저장됩니다.

if (item.type == "insert") {
    item.dataItem.id = (item.sourceIndex + 1).toString();
    if (item.sourceParentIndex) {
        item.dataItem.parentId = item.sourceParentIndex + 1;
    }
    const params = { method: "POST", body: JSON.stringify(item.dataItem) };
    params.headers = { 'Content-Type': 'application/json; charset=utf-8' };
    results.push(fetch(url, params).then(resp => {
        console.log(resp)
        if (resp.ok) {
            return { succeed: true, data: resp.json() };
        } else {
            return { succeed: false, reason: resp.statusText };
        }
    }));
}

Read (작업 불러오기)

서버로부터 데이터를 가져와 간트 시트에 채웁니다.

remote: {
    read: {
        url: apiUrl,
    },
}

Update (작업 수정)

작업의 기간, 비용, 종속성 등 속성을 수정합니다. 업데이트는 배치 처리를 위해 큐에 저장됩니다.

if (item.type == "update") {
    const params = { method: "PUT", body: JSON.stringify(item.dataItem) };
    params.headers = { 'Content-Type': 'application/json; charset=utf-8' };
    results.push(fetch(url + item.dataItem.id, params).then(resp => {
        if (resp.ok) {
            return { succeed: true, data: resp.json() };
        } else {
            return { succeed: false, reason: resp.statusText };
        }
    }));
}

Delete (작업 삭제)

간트 시트에서 지정된 작업을 제거합니다. 삭제 작업은 큐에 저장되고 배치 모드로 처리됩니다.

if (item.type == "delete") {
    const params = { method: "DELETE" };
    params.headers = { 'Content-Type': 'application/json; charset=utf-8' };
    results.push(fetch(url + item.dataItem.id, params).then(resp => {
        if (resp.ok) {
            return { succeed: true, data: resp.json() };
        } else {
            return { succeed: false, reason: resp.statusText };
        }
    }));
}


배치 모드 동기화

간트 시트는 이러한 작업에 대해 배치 모드만을 지원합니다.


간트 시트를 사용하려면 배치 모드를 지원하는 서버가 필요하거나, 서버 측에서 배치 업데이트를 처리할 수 있도록 로직을 구현해야 합니다.

서버 측 지원이 불가능한 경우, 클라이언트 측에서 유사한 배치 모드를 구현해야 합니다.

// 변경 사항 제출
ganttSheet.submitChanges();


스키마 구성

스키마는 간트 시트의 작업 구조를 정의하며, 계층 구조와 열 속성을 포함합니다.

var myTable1 = dataManager.addTable("myTable1", {
    batch: true,
    remote: {
        read: {
            url: apiUrl,
        },
        batch: function (changes) {
            return sendRequest(apiUrl, { body: changes });
        }
    },
    schema: {
        hierarchy: {
            type: "Parent",
            column: "parentId",
        },
        columns: {
            id: { isPrimaryKey: true },
            taskNumber: { dataType: "rowOrder" },
        }
    }
});


뷰를 간트 시트에 바인딩

작업 뷰를 간트 시트에 바인딩하여 시각화 및 상호작용이 가능하도록 합니다.

var ganttSheet = spread.addSheetTab(0, "GanttSheet1", GC.Spread.Sheets.SheetType.ganttSheet);
var view = myTable1.addView("myView1", [
    { value: "taskNumber", caption: "NO", width: 60 },
    { value: '=CONCAT("(L",LEVEL(),"-",LEVELROWNUMBER(),")")', caption: "L" },
    { value: "name", caption: "Task Name", width: 200 },
    { value: "duration", caption: "Duration", width: 90 },
    { value: "predecessors", caption: "Predecessors", width: 60 },
    { value: "cost", caption: "Cost", style: { formatter: "$0" } }
]);
view.fetch().then(function () {
    ganttSheet.bindGanttView(view);
});


사용자 정의 요청

sendRequest 함수는 배치 작업을 위한 서버 요청을 처리합니다. 이는 서버 측에서 배치 처리를 지원하지 않을 경우, 클라이언트 측에서 유사 배치 모드를 구현하는 데 필수적입니다.

function sendRequest(url, options) {
    const results = [];
    for (const item of options.body) {
        // 삽입, 업데이트, 삭제 로직
    }
    return Promise.all(results);
}

예시

CRUD 작업이 어떻게 작동하는지 명확히 이해할 수 있도록, 개별 코드 스니펫을 결합한 전체 구현 예제가 아래에 제공됩니다.

Ask ChatGPT

 <script>
     function getBaseApiUrl() {
         return 'https://developer.mescius.com/spreadjs/demos/features/ganttsheet/overview/purejs'.match(/http.+spreadjs\/demos\//)[0] + 'server/api';
     }

     let spread = new GC.Spread.Sheets.Workbook("spreadjs-host");
     spread.options.tabStripRatio = 0.8;
     spread.setSheetCount(0);

     function sendRequest(url, options) {
         const results = [];

         for (const item of options.body) {
             if (item.type == "insert") {
                 item.dataItem.id = (item.sourceIndex + 1).toString();
                 if (item.sourceParentIndex) {
                     item.dataItem.parentId = item.sourceParentIndex + 1;
                 }
                 const params = { method: "POST", body: JSON.stringify(item.dataItem) };
                 params.headers = { 'Content-Type': 'application/json; charset=utf-8' };
                 results.push(fetch(url, params).then(resp => {
                     console.log(resp)
                     if (resp.ok) {
                         return { succeed: true, data: resp.json() };
                     } else {
                         return { succeed: false, reason: resp.statusText };
                     }
                 }));
             }
             else if (item.type == "update") {
                 const params = { method: "PUT", body: JSON.stringify(item.dataItem) };
                 params.headers = { 'Content-Type': 'application/json; charset=utf-8' };

                 results.push(fetch(url + item.dataItem.id, params).then(resp => {
                     if (resp.ok) {
                         return { succeed: true, data: resp.json() };
                     } else {
                         return { succeed: false, reason: resp.statusText };
                     }
                 }));
             }
             else if (item.type == "delete") {
                 const params = { method: "DELETE" };
                 params.headers = { 'Content-Type': 'application/json; charset=utf-8' };

                 results.push(fetch(url + item.dataItem.id, params).then(resp => {
                     if (resp.ok) {
                         return { succeed: true, data: resp.json() };
                     } else {
                         return { succeed: false, reason: resp.statusText };
                     }
                 }));
             }
         }
         return Promise.all(results);
     }

     var tableName = "Gantt_Id";
     var baseApiUrl = getBaseApiUrl();
     var apiUrl = baseApiUrl + "/" + tableName;
     var dataManager = spread.dataManager();

     var myTable1 = dataManager.addTable("myTable1", {
         batch: true,
         remote: {
             read: {
                 url: apiUrl,
             },

             batch: function (changes) {
                 return sendRequest(apiUrl, { body: changes });
             }
         },
         schema: {
             hierarchy: {
                 type: "Parent",
                 column: "parentId"
             },
             columns: {
                 id: { isPrimaryKey: true },
                 taskNumber: { dataType: "rowOrder" }
             }
         }
     });

     var ganttSheet = spread.addSheetTab(0, "GanttSheet1", GC.Spread.Sheets.SheetType.ganttSheet);
     var view = myTable1.addView("myView1", [
         { value: "taskNumber", caption: "NO", width: 60 },
         { value: '=CONCAT("(L",LEVEL(),"-",LEVELROWNUMBER(),")")', caption: "L" },
         { value: "name", caption: "Task Name", width: 200 },
         { value: "duration", caption: "Duration", width: 90 },
         { value: "predecessors", caption: "Predecessors", width: 60 },
         { value: "cost", caption: "Cost", style: { formatter: "$0" } }
     ]);
     view.fetch().then(function () {
         ganttSheet.bindGanttView(view);
     });

     document.getElementById("btn").onclick = () => {
         ganttSheet.submitChanges();
     }
 </script>