[]
간트 시트는 Create, Read, Update, Delete(CRUD)를 포함한 행(row) 작업을 통해 사용자가 데이터와 상호작용할 수 있도록 합니다.
이러한 작업은 편리하게 수정된 행 데이터를 데이터베이스와 동기화할 수 있도록 합니다.
다음은 행 작업으로 사용할 수 있는 GanttSheet 클래스 메서드입니다:
메서드 | 설명 |
---|---|
| 테이블에 새 행을 추가합니다. |
| 지정된 행을 테이블에서 제거합니다. |
| 수정되거나 삽입된 행을 포함하여 지정된 행의 변경 사항을 데이터 매니저에 저장합니다. |
| 지정된 행의 변경 사항을 초기화합니다. |
다음 샘플 코드를 통해 간트 시트에서의 CRUD 작업을 이해해봅시다.
간트 시트에 새로운 작업을 추가합니다.
여기에는 계층적 관계(예: 상위-하위 관계)도 포함됩니다. 작업은 배치 모드로 큐에 저장됩니다.
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 };
}
}));
}
서버로부터 데이터를 가져와 간트 시트에 채웁니다.
remote: {
read: {
url: apiUrl,
},
}
작업의 기간, 비용, 종속성 등 속성을 수정합니다. 업데이트는 배치 처리를 위해 큐에 저장됩니다.
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 };
}
}));
}
간트 시트에서 지정된 작업을 제거합니다. 삭제 작업은 큐에 저장되고 배치 모드로 처리됩니다.
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>