From 215dec27d796ee9b5be7857a425093a53db84332 Mon Sep 17 00:00:00 2001 From: mengshukeji Date: Fri, 20 Nov 2020 17:37:23 +0800 Subject: [PATCH] feat(hook): add hook function 1.add hook function:cellAllRenderBefore / updated 2.update docs --- docs/guide/config.md | 8 ---- docs/zh/guide/api.md | 2 +- docs/zh/guide/config.md | 23 ++++++----- src/controllers/alternateformat.js | 2 +- src/controllers/conditionformat.js | 2 +- src/controllers/controlHistory.js | 5 +++ src/controllers/dataVerificationCtrl.js | 4 +- src/controllers/filter.js | 6 +-- src/controllers/handler.js | 4 +- src/controllers/hyperlinkCtrl.js | 2 +- src/controllers/imageCtrl.js | 2 +- src/controllers/listener.js | 13 ++++++ src/controllers/menuButton.js | 6 +-- src/controllers/pivotTable.js | 2 +- src/controllers/postil.js | 2 +- src/controllers/rowColumnOperation.js | 18 ++++----- src/controllers/sheetBar.js | 6 +-- src/controllers/sheetmanage.js | 2 +- src/core.js | 2 + src/global/api.js | 14 +++---- src/global/draw.js | 3 ++ src/global/refresh.js | 12 +++--- src/index.html | 7 ++++ src/store/index.js | 2 +- src/utils/util.js | 53 ++++++++++++++++++++++++- 25 files changed, 139 insertions(+), 63 deletions(-) create mode 100644 src/controllers/listener.js diff --git a/docs/guide/config.md b/docs/guide/config.md index dea35cded..59bfe9fa9 100644 --- a/docs/guide/config.md +++ b/docs/guide/config.md @@ -912,14 +912,6 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Parameter: - {Object} [book]:Configuration of the entire workbook (options) ------------- -### updateBefore -- Type: Function -- Default: null -- Usage: The method executed before each operation in collaborative editing updates the data. When undoing and redoing, it is also an operation, of course, the hook function will be triggered. -- Parameter: - - {Object} [operate]: The history information of this operation will have different history records according to different operations. Refer to the source code [History](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/controlHistory.js ) - ------------ ### updated - Type: Function diff --git a/docs/zh/guide/api.md b/docs/zh/guide/api.md index fbac42003..2ce1d6ef5 100644 --- a/docs/zh/guide/api.md +++ b/docs/zh/guide/api.md @@ -391,7 +391,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 - 在第1列的位置插入3行空白行 - `luckysheet.insertRow(0, { number: 3 })` + `luckysheet.insertColumn(0, { number: 3 })` ------------ diff --git a/docs/zh/guide/config.md b/docs/zh/guide/config.md index b3a8a4663..467df3bbf 100644 --- a/docs/zh/guide/config.md +++ b/docs/zh/guide/config.md @@ -605,6 +605,8 @@ Luckysheet开放了更细致的自定义配置选项,分别有 钩子函数统一配置在`options.hook`下,可以分别针对单元格、sheet页、表格创建配置hook。 +> 使用案例可参考源码 [src/index.html](https://github.com/mengshukeji/Luckysheet/blob/master/src/index.html) + ## 单元格 ### cellRenderBefore @@ -643,6 +645,16 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - {Object} [ctx]: 当前画布的context ------------ +### cellAllRenderBefore + +- 类型:Function +- 默认值:null +- 作用:所有单元格渲染之前执行的方法。在内部,这个方法加在了`luckysheetDrawMain`渲染表格之前。 +- 参数: + - {Object} [data]: 当前工作表二维数组数据 + - {Object} [sheet]:当前sheet对象 + - {Object} [ctx]: 当前画布的context +------------ ### cellEditBefore (TODO) - 类型:Function @@ -1217,18 +1229,9 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 参数: - {Object} [book]: 整个工作簿的配置(options) ------------- -### updateBefore -(TODO) -- 类型:Function -- 默认值:null -- 作用:协同编辑中的每次操作更新数据之前执行的方法,撤销重做时因为也算一次操作,也会触发此钩子函数。 -- 参数: - - {Object} [operate]: 本次操作的历史记录信息,根据不同的操作,会有不同的历史记录,参考源码 [历史记录](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/controlHistory.js) - ------------ ### updated -(TODO) + - 类型:Function - 默认值:null - 作用:协同编辑中的每次操作后执行的方法,即客户端每执行一次表格操作,Luckysheet将这次操作存到历史记录中后触发,撤销重做时因为也算一次操作,也会触发此钩子函数。 diff --git a/src/controllers/alternateformat.js b/src/controllers/alternateformat.js index da15a7471..5c0cf8f76 100644 --- a/src/controllers/alternateformat.js +++ b/src/controllers/alternateformat.js @@ -1205,7 +1205,7 @@ const alternateformat = { }, ref: function(historyRules, currentRules){ if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = {}; redo["type"] = "updateAF"; diff --git a/src/controllers/conditionformat.js b/src/controllers/conditionformat.js index a5c16d3d7..235d9c261 100644 --- a/src/controllers/conditionformat.js +++ b/src/controllers/conditionformat.js @@ -3708,7 +3708,7 @@ const conditionformat = { }, ref: function(historyRules, currentRules){ if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = {}; redo["type"] = "updateCF"; diff --git a/src/controllers/controlHistory.js b/src/controllers/controlHistory.js index 73def60ba..67f48e4bc 100644 --- a/src/controllers/controlHistory.js +++ b/src/controllers/controlHistory.js @@ -24,6 +24,7 @@ import { import { getSheetIndex } from '../methods/get'; import Store from '../store'; import { selectHightlightShow } from './select'; +import method from '../global/method'; function formulaHistoryHanddler(ctr, type="redo"){ if(ctr==null){ @@ -426,6 +427,9 @@ const controlHistory = { selectHightlightShow(); } Store.clearjfundo = true; + + // 钩子函数 + method.createHookFunction('updated',ctr) }, undo: function () { if (Store.jfundo.length == 0) { @@ -736,6 +740,7 @@ const controlHistory = { selectHightlightShow(); } Store.clearjfundo = true; + } }; diff --git a/src/controllers/dataVerificationCtrl.js b/src/controllers/dataVerificationCtrl.js index d7791946c..06904fc21 100644 --- a/src/controllers/dataVerificationCtrl.js +++ b/src/controllers/dataVerificationCtrl.js @@ -1531,7 +1531,7 @@ const dataVerificationCtrl = { let _this = this; if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = {}; redo["type"] = "updateDataVerification"; @@ -1557,7 +1557,7 @@ const dataVerificationCtrl = { let _this = this; if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = {}; redo["type"] = "updateDataVerificationOfCheckbox"; diff --git a/src/controllers/filter.js b/src/controllers/filter.js index 11c12238e..4561a1aa2 100644 --- a/src/controllers/filter.js +++ b/src/controllers/filter.js @@ -1053,7 +1053,7 @@ function initialFilterHandler(){ redo["caljs"] = caljs; } - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } @@ -1300,7 +1300,7 @@ function initialFilterHandler(){ }); redo["optiongroups"] = optiongroups; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); $('#luckysheet-filter-selected-sheet' + Store.currentSheetIndex + ', #luckysheet-filter-options-sheet' + Store.currentSheetIndex).remove(); @@ -1775,7 +1775,7 @@ function initialFilterHandler(){ redo["caljs"] = caljs; } - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } diff --git a/src/controllers/handler.js b/src/controllers/handler.js index b4d7ccf0d..a5ff0f631 100644 --- a/src/controllers/handler.js +++ b/src/controllers/handler.js @@ -3634,7 +3634,7 @@ export default function luckysheetHandler() { let images = imageCtrl.moveChangeSize("row", Store.luckysheet_rows_change_size_start[1], size); if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "resize", @@ -3736,7 +3736,7 @@ export default function luckysheetHandler() { let images = imageCtrl.moveChangeSize("column", Store.luckysheet_cols_change_size_start[1], size); if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "resize", diff --git a/src/controllers/hyperlinkCtrl.js b/src/controllers/hyperlinkCtrl.js index fb63fcf59..99968cfa0 100644 --- a/src/controllers/hyperlinkCtrl.js +++ b/src/controllers/hyperlinkCtrl.js @@ -326,7 +326,7 @@ const hyperlinkCtrl = { let _this = this; if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = {}; redo["type"] = "updateHyperlink"; diff --git a/src/controllers/imageCtrl.js b/src/controllers/imageCtrl.js index b1f2c20b0..fcc9485b7 100644 --- a/src/controllers/imageCtrl.js +++ b/src/controllers/imageCtrl.js @@ -1066,7 +1066,7 @@ const imageCtrl = { let images = _this.images; if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "imageCtrl", diff --git a/src/controllers/listener.js b/src/controllers/listener.js new file mode 100644 index 000000000..5c5ad1e71 --- /dev/null +++ b/src/controllers/listener.js @@ -0,0 +1,13 @@ +/** + * Monitor special variables + */ +import {createProxy} from '../utils/util' +import Store from '../store/index' +const initListener = function(){ + createProxy(Store,['jfredo']) +} + + +export { + initListener +} \ No newline at end of file diff --git a/src/controllers/menuButton.js b/src/controllers/menuButton.js index cf6df70d8..0b9a3d58a 100644 --- a/src/controllers/menuButton.js +++ b/src/controllers/menuButton.js @@ -962,7 +962,7 @@ const menuButton = { cfg["borderInfo"].push(borderInfo); if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = []; @@ -1121,7 +1121,7 @@ const menuButton = { cfg["borderInfo"].push(borderInfo); if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = []; @@ -3356,7 +3356,7 @@ const menuButton = { } if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "mergeChange", "sheetIndex": Store.currentSheetIndex, diff --git a/src/controllers/pivotTable.js b/src/controllers/pivotTable.js index 90c027517..e83f3e47a 100644 --- a/src/controllers/pivotTable.js +++ b/src/controllers/pivotTable.js @@ -724,7 +724,7 @@ const pivotTable = { redo["pivotTablecur"] = pivotTable; if(Store.clearjfundo){ - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } diff --git a/src/controllers/postil.js b/src/controllers/postil.js index 0ebaaa315..66fd3546f 100644 --- a/src/controllers/postil.js +++ b/src/controllers/postil.js @@ -839,7 +839,7 @@ const luckysheetPostil = { }, ref: function(data, rc){ if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "postil", diff --git a/src/controllers/rowColumnOperation.js b/src/controllers/rowColumnOperation.js index a7586fe69..98899293b 100644 --- a/src/controllers/rowColumnOperation.js +++ b/src/controllers/rowColumnOperation.js @@ -1578,7 +1578,7 @@ export function rowColumnOperationInitial(){ redo["config"] = $.extend(true, {}, Store.config); redo["curconfig"] = cfg; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } @@ -1621,7 +1621,7 @@ export function rowColumnOperationInitial(){ redo["config"] = $.extend(true, {}, Store.config); redo["curconfig"] = cfg; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } @@ -1693,7 +1693,7 @@ export function rowColumnOperationInitial(){ redo["config"] = $.extend(true, {}, Store.config); redo["curconfig"] = cfg; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } @@ -1733,7 +1733,7 @@ export function rowColumnOperationInitial(){ redo["config"] = $.extend(true, {}, Store.config); redo["curconfig"] = cfg; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } @@ -1779,7 +1779,7 @@ export function rowColumnOperationInitial(){ // redo["config"] = $.extend(true, {}, Store.config); // redo["curconfig"] = cfg; - // Store.jfundo = []; + // Store.jfundo.length = 0; // Store.jfredo.push(redo); // } @@ -1821,7 +1821,7 @@ export function rowColumnOperationInitial(){ // redo["config"] = $.extend(true, {}, Store.config); // redo["curconfig"] = cfg; - // Store.jfundo = []; + // Store.jfundo.length = 0; // Store.jfredo.push(redo); // } @@ -1865,7 +1865,7 @@ export function rowColumnOperationInitial(){ // redo["config"] = $.extend(true, {}, Store.config); // redo["curconfig"] = cfg; - // Store.jfundo = []; + // Store.jfundo.length = 0; // Store.jfredo.push(redo); // } @@ -1907,7 +1907,7 @@ export function rowColumnOperationInitial(){ // redo["config"] = $.extend(true, {}, Store.config); // redo["curconfig"] = cfg; - // Store.jfundo = []; + // Store.jfundo.length = 0; // Store.jfredo.push(redo); // } @@ -2138,7 +2138,7 @@ export function rowColumnOperationInitial(){ } if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "resize", "ctrlType": type, diff --git a/src/controllers/sheetBar.js b/src/controllers/sheetBar.js index bafd920fe..a3659fd18 100644 --- a/src/controllers/sheetBar.js +++ b/src/controllers/sheetBar.js @@ -71,7 +71,7 @@ function showsheetconfigmenu() { redo["oldcolor"] = oldcolor; redo["color"] = color; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } } @@ -96,7 +96,7 @@ function showsheetconfigmenu() { redo["oldcolor"] = oldcolor; redo["color"] = null; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } }); @@ -264,7 +264,7 @@ export function initialSheetBar(){ redo["oldtxt"] = oldtxt; redo["txt"] = txt; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } }); diff --git a/src/controllers/sheetmanage.js b/src/controllers/sheetmanage.js index 64bc6e943..8e93d2aef 100644 --- a/src/controllers/sheetmanage.js +++ b/src/controllers/sheetmanage.js @@ -234,7 +234,7 @@ const sheetmanage = { server.saveParam("sha", null, $.extend(true, {}, sheetconfig)); if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = {}; redo["type"] = "addSheet"; redo["sheetconfig"] = $.extend(true, {}, sheetconfig); diff --git a/src/core.js b/src/core.js index 07178afe0..d815385b7 100644 --- a/src/core.js +++ b/src/core.js @@ -37,6 +37,7 @@ import * as api from './global/api'; import flatpickr from 'flatpickr' import Mandarin from 'flatpickr/dist/l10n/zh.js' +import { initListener } from './controllers/listener'; let luckysheet = {}; @@ -181,6 +182,7 @@ function initialWorkBook(){ orderByInitial();//menu bar orderby function initialization zoomInitial();//zoom method initialization printInitial();//print initialization + initListener(); } //获取所有表格数据 diff --git a/src/global/api.js b/src/global/api.js index 9342b31a1..36cfb8abb 100644 --- a/src/global/api.js +++ b/src/global/api.js @@ -1082,7 +1082,7 @@ export function hideRowOrColumn(type, startIndex, endIndex, options = {}) { redo["config"] = $.extend(true, {}, file.config); redo["curconfig"] = cfg; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } @@ -1140,7 +1140,7 @@ export function showRowOrColumn(type, startIndex, endIndex, options = {}) { redo["config"] = $.extend(true, {}, file.config); redo["curconfig"] = cfg; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } @@ -2830,7 +2830,7 @@ export function setRangeMerge(type, options = {}) { if(order == curSheetOrder){ if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "mergeChange", "sheetIndex": file.index, @@ -2973,7 +2973,7 @@ export function cancelRangeMerge(options = {}) { if(order == curSheetOrder){ if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "mergeChange", "sheetIndex": file.index, @@ -4522,7 +4522,7 @@ export function setSheetAdd(options = {}) { server.saveParam("shr", null, orders); if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = {}; redo["type"] = "addSheet"; redo["sheetconfig"] = $.extend(true, {}, sheetconfig); @@ -4793,7 +4793,7 @@ export function setSheetName(name, options = {}) { redo["oldtxt"] = oldtxt; redo["txt"] = name; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } @@ -4842,7 +4842,7 @@ export function setSheetColor(color, options = {}) { redo["oldcolor"] = oldcolor; redo["color"] = color; - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push(redo); } diff --git a/src/global/draw.js b/src/global/draw.js index 5f5dfbc3e..436439958 100644 --- a/src/global/draw.js +++ b/src/global/draw.js @@ -568,6 +568,9 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of let borderOffset = {}; let bodrder05 = 0.5;//Default 0.5 + + // 钩子函数 + method.createHookFunction("cellAllRenderBefore",Store.flowdata,sheetFile,luckysheetTableContent); for (let r = dataset_row_st; r <= dataset_row_ed; r++) { let start_r; diff --git a/src/global/refresh.js b/src/global/refresh.js index 2399035e5..4b8ad3327 100644 --- a/src/global/refresh.js +++ b/src/global/refresh.js @@ -63,7 +63,7 @@ function jfrefreshgrid(data, range, allParam, isRunExecFunction = true, isRefres let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]; if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let curConfig; if(cfg == null){ @@ -274,7 +274,7 @@ function jfrefreshgridall(colwidth, rowheight, data, cfg, range, ctrlType, ctrlV } if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; redo["data"] = Store.flowdata; redo["curdata"] = data; @@ -337,7 +337,7 @@ function jfrefreshrange(data, range, cdformat) { clearTimeout(refreshCanvasTimeOut); if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "rangechange", @@ -421,7 +421,7 @@ function jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf, } if(Store.clearjfundo){ - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": ctrlType, @@ -639,7 +639,7 @@ function jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf, dataVeri } if(Store.clearjfundo){ - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "deleteCell", @@ -780,7 +780,7 @@ function jfrefreshgrid_pastcut(source, target, RowlChange){ if(Store.clearjfundo){ - Store.jfundo = []; + Store.jfundo.length = 0; Store.jfredo.push({ "type": "pasteCut", diff --git a/src/index.html b/src/index.html index 9142e86b9..42ca1834c 100644 --- a/src/index.html +++ b/src/index.html @@ -92,6 +92,13 @@ sheetMouseup:function(cell,postion,sheetFile,moveState,ctx){ // console.log(cell,postion,sheetFile,moveState,ctx); }, + cellAllRenderBefore:function(data,sheetFile,ctx){ + // console.info(data,sheetFile,ctx) + }, + updated:function(operate){ + // console.info(operate) + } + }, data: diff --git a/src/store/index.js b/src/store/index.js index 6134f8776..820c9b7d2 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -81,8 +81,8 @@ const Store = { luckysheet_cell_selected_extend_time: null, clearjfundo: true, - jfredo: [], jfundo: [], + jfredo: [], lang: 'en', //language createChart: '', highlightChart: '', diff --git a/src/utils/util.js b/src/utils/util.js index 0eef1df99..8a32f413f 100644 --- a/src/utils/util.js +++ b/src/utils/util.js @@ -4,6 +4,7 @@ import { isdatatype, isdatatypemulti } from '../global/datecontroll'; import { hasChinaword,isRealNum } from '../global/validate'; import Store from '../store'; import locale from '../locale/locale'; +import method from '../global/method'; /** * Common tool methods @@ -751,7 +752,56 @@ function openSelfModel(id, isshowMask=true){ } } +/** + * 监控对象变更 + * @param {*} data + */ +const createProxy = (data,list=[]) => { + if (typeof data === 'object' && data.toString() === '[object Object]') { + for (let k in data) { + if(list.includes(k)){ + if (typeof data[k] === 'object') { + defineObjectReactive(data, k, data[k]) + } else { + defineBasicReactive(data, k, data[k]) + } + } + } + } +} + +function defineObjectReactive(obj, key, value) { + // 递归 + // createProxy(value) + obj[key] = new Proxy(value, { + set(target, property, val, receiver) { + if (property !== 'length') { + setTimeout(() => { + // 钩子函数 + method.createHookFunction('updated',val) + }, 0); + } + return Reflect.set(target, property, val, receiver) + } + }) +} + +function defineBasicReactive(obj, key, value) { + Object.defineProperty(obj, key, { + enumerable: true, + configurable: false, + get() { + return value + }, + set(newValue) { + if (value === newValue) return + console.log(`发现 ${key} 属性 ${value} -> ${newValue}`) + value = newValue + } + }) +} + export { isJsonString, common_extend, @@ -777,5 +827,6 @@ export { loadLinks, luckysheetContainerFocus, transformRangeToAbsolute, - openSelfModel + openSelfModel, + createProxy } \ No newline at end of file