기본적으로 테이블 시트는 로컬 데이터 관리자와 상호 작용합니다. 원격 데이터베이스와 변경된 데이터를 동기화하려면 먼저 AutoSync 또는 Batch 모드를 활성화하십시오.
이 데모에서는 Batch 모드를 사용합니다.
AutoSync 모드
이 모드는 주로 빈도가 낮은 데이터 작업 시나리오에 적합합니다. 행 작업에서 버튼을 사용하거나 API를 사용하여 행과 상호 작용하면 해당하는 변경 사항이 있는 요청이 시작되어 즉시 서버로 전송됩니다.
표 초기화에서 AutoSync 모드를 활성화하려면 아래 샘플 코드를 참조하십시오.
Batch 모드
이 모드는 데이터를 자주 조작하는 시나리오에 주로 적합합니다. 이 모드에서는 각 행 작업을 순서대로 저장한 후 모든 변경 사항을 컬렉션으로 패키지화한 다음 네트워크 리소스를 절약하기 위해 서버로 한 번에 전송합니다.
Batch 모드를 활성화하고 표 초기화에서 BatchApiUrl를 지정하려면 다음 샘플 코드를 참조하십시오.
그런 다음 아래와 같이 모든 변경 사항을 제출하거나 취소할 수 있습니다.
변경 사항 가져오기
또한 변경 사항을 서버에 저장하기 전에 가져올 수도 있습니다.
요청 및 응답
작업
요청 유형
요청 데이터
응답 데이터
update
POST
업데이트된 데이터
업데이트된 데이터
read
GET
데이터 없음
레코드 배열
delete
DELETE
삭제된 데이터 또는 데이터 배열
제한 없음
create
POST
삽입된 데이터
삽입된 데이터
batch
POST
각 개체에 'type' 속성이 포함된 개체 배열입니다.
이 작업 유형은 'update', 'insert' 또는 'delete'일 수 있습니다.
'dataItem' 속성은 현재 레코드입니다.
'sourceIndex' 속성은 레코드 인덱스입니다.
선택 사항인 'oldDataItem' 속성은 원본 레코드입니다.
예는 다음과 같습니다.
[ {"type":"delete","dataItem":{...}, "sourceIndex":5},
{"type":"insert","dataItem":{...}, "sourceIndex":3},
{"type":"update","dataItem":{...}, "oldDataItem":{...}, "oldDataItem":{...}, "sourceIndex":1}]
각 개체에 작업의 성공이나 실패를 나타내는 'succeed' 속성이 포함되어 있는 개체 배열과 현재 레코드이며 'insert' 작업에만 해당되는 선택적인 'data' 속성입니다.
예는 다음과 같습니다.
[{"succeed":true}, {"succeed":false}, {"succeed": true}]
/*REPLACE_MARKER*/
/*DO NOT DELETE THESE COMMENTS*/
var tableName = "Employee";
var baseApiUrl = getBaseApiUrl();
var apiUrl = baseApiUrl + "/" + tableName;
var batchApiUrl = baseApiUrl + "/" + tableName + 'Collection';
var tablesheetName = 'MyTableSheet';
var spread, sheet, view, selections, table;
window.onload = function() {
spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 0 });
initSpread(spread);
bindEvents();
};
function initSpread(spread) {
spread.suspendPaint();
spread.clearSheets();
spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader;
//init a data manager
var dataManager = spread.dataManager();
myTable = dataManager.addTable("myTable", {
remote: {
read: {
url: apiUrl
},
update: {
url: apiUrl,
method: 'PUT'
},
create: {
url: apiUrl
},
delete: {
url: apiUrl
},
batch: {
url: batchApiUrl
}
},
batch: true,
schema: {
columns: {
"Id": { dataType: "number" },
"LastName": { dataType: "string" },
"FirstName": { dataType: "string" },
"HomePhone": { dataType: "string" },
"Notes": { dataType: "string" }
}
}
});
table = myTable;
//init a table sheet
sheet = spread.addSheetTab(0, tablesheetName, 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);
//bind a view to the table sheet
myTable.fetch().then(function() {
view = myTable.addView("myView", [
{ value: "Id", width: 50, caption: "ID" },
{ value: "FirstName", width: 100, caption: "First Name" },
{ value: "LastName", width: 100, caption: "Last Name" },
{ value: "HomePhone", width: 120, caption: "Home Phone" },
{ value: "Title", width: 150, caption: "Title" }
]);
sheet.setDataView(view);
});
selections = [{row: 0, rowCount: 1, col: 0, colCount: 1}];
spread.bind(GC.Spread.Sheets.Events.SelectionChanged, function(e, args) {
selections = args.newSelections;
});
spread.resumePaint();
}
function bindEvents() {
var removeButton = document.getElementById('remove');
removeButton.addEventListener('click', function() {
traverseSelectionsRowsWithOperation(function(row) {
sheet.removeRow(row);
});
});
var saveButton = document.getElementById('save');
saveButton.addEventListener('click', function() {
traverseSelectionsRowsWithOperation(function(row) {
sheet.saveRow(row);
});
});
var resetButton = document.getElementById('reset');
resetButton.addEventListener('click', function() {
traverseSelectionsRowsWithOperation(function(row) {
sheet.resetRow(row);
});
});
var saveAllButton = document.getElementById('save-all');
saveAllButton.addEventListener('click', function() {
spread.commandManager().SaveAll.execute(spread, { sheetName: tablesheetName });
});
var submitButton = document.getElementById('submit');
submitButton.addEventListener('click', function() {
sheet.submitChanges();
});
var discardButton = document.getElementById('discard');
discardButton.addEventListener('click', function() {
sheet.cancelChanges();
});
var getChangesButton = document.getElementById("getChanges");
getChangesButton.addEventListener('click', function () {
var changesPanel = document.getElementById("changesPanel");
var changes = formatChanges(sheet.getChanges());
changesPanel.innerHTML = changes;
});
}
function traverseSelectionsRowsWithOperation(operation) {
if (selections) {
for (var i = 0; i < selections.length; i++) {
var selection = selections[i];
var row = selection.row;
var rowCount = selection.rowCount;
for (var r = row + rowCount - 1; r >= row; r--) {
operation(r);
}
}
}
}
function getBaseApiUrl() {
return window.location.href.match(/http.+spreadjs\/learn-spreadjs\//)[0] + 'server/api';
}
function formatChanges(changes) {
var json = JSON.stringify(changes, function (k, v) {
if (k === "dataItem" || k === "oldDataItem") {
return {
Id: v.Id,
FirstName: v.FirstName,
LastName: v.LastName,
HomePhone: v.HomePhone,
Title: v.Title
};
}
return v;
}, 2);
return json;
}
<!doctype html>
<html style="height:100%;font-size:14px;">
<head>
<meta name="spreadjs culture" content="ko-kr" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<!-- Promise Polyfill for IE, https://www.npmjs.com/package/promise-polyfill -->
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script>
<script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-resources-ko/dist/gc.spread.sheets.resources.ko.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="sample-tutorial">
<div id="ss" class="sample-spreadsheets"></div>
<div id="options-container" class="options-container">
<fieldset>
<legend>Active Row Operations</legend>
<div class="field-line">
<input id="remove" type="button" value="Remove">
</div>
<div class="field-line">
<input id="save" type="button" value="Save">
</div>
<div class="field-line">
<input id="reset" type="button" value="Reset">
</div>
</fieldset>
<fieldset>
<legend>Save All Rows</legend>
<div class="field-line">
<input id="save-all" type="button" value="Save All">
</div>
</fieldset>
<fieldset>
<legend>Batch Operations</legend>
<div class="field-line">
<input type="button" value="Submit" id="submit">
</div>
<div class="field-line">
<input type="button" value="Discard" id="discard">
</div>
</fieldset>
<fieldset>
<legend>Get Changes</legend>
<div class="field-line">
<input type="button" value="Get Changes" id="getChanges">
</div>
<div class="field-line">
<textarea id="changesPanel"></textarea>
</div>
</fieldset>
</div>
</div>
</html>
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
fieldset {
padding: 6px;
margin: 0;
margin-top: 10px;
}
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: calc(100% - 280px);
height: 100%;
overflow: hidden;
float: left;
}
.options-container {
float: right;
width: 280px;
padding: 12px;
height: 100%;
box-sizing: border-box;
background: #fbfbfb;
overflow: auto;
}
fieldset span,
fieldset input,
fieldset select {
display: inline-block;
text-align: left;
}
fieldset input[type=text] {
width: calc(100% - 58px);
}
fieldset input[type=button] {
width: 100%;
text-align: center;
}
fieldset select {
width: calc(100% - 50px);
}
.field-line {
margin-top: 4px;
}
.field-inline {
display: inline-block;
vertical-align: middle;
}
fieldset label.field-inline {
width: 100px;
}
fieldset input.field-inline {
width: calc(100% - 100px - 12px);
}
.required {
color: red;
font-weight: bold;
}
#fields {
display: none;
}
#fields.show {
display: block;
}
#changesPanel {
width: 100%;
height: 300px;
}