GooFlow流程設計工具結合Easyui設計工作流

爲何使用gooflow:1、兼容性好

                       2、擴展點很多可以個性化設計

                       3、配有api文檔

                       4、json格式的數據傳輸

由於最近項目需要,急需設計一個流程,考慮到時間問題,和用戶個性化的需求,沒辦法跟現在項目的後臺集成,所以考慮到選擇一款jquery插件,並通過存儲過程來集成現在的業務模塊。

 

直接上圖了:

雙擊節點可以選擇人員

雙擊連接線可以選擇條件

使用gooflow版本爲0.4的 網上可以搜到 另外當前版本有些bug需要自己改。需要提供幫助的可以加我QQ:512948935

gooflow版本爲0.6

後臺使用的是mvc+spring+NHibernate,主要是保存比較麻煩。

 前臺js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<script type="text/javascript">
    var property = {
        toolBtns: ["start""end""task"],
        haveHead: true,
        headBtns: ["save""undo""redo""reload"], //如果haveHead=true,則定義HEAD區的按鈕
        haveTool: true,
        haveGroup: true,
        useOperStack: true
    };
    var remark = {
        cursor: "選擇指針",
        direct: "轉換連線",
        start: "開始結點",
        end: "結束結點",
        task: "任務結點",
        group: "組織劃分框編輯開關"
    };
    var gooFlow, focusId, flow_title, flowID;
    $(function () {
        gooFlow = $.createGooFlow($("#flow"), property);
        flow_title = getUrlParam1("title");
        flowID = getUrlParam("flowID");
        if (flow_title != "") {
            //自適應調整
            gooFlow.reinitSize($(this).width() - 5, $(parent).height() - 25);
            gooFlow.setTitle(flow_title + "·流程繪製");
            parent.$('#div_layout').layout('panel''center').panel({
                onResize: function (width, height) {
                    gooFlow.reinitSize(width - 5, height - 30);
                }
            });
        }
        else
            gooFlow.reinitSize($(this).width() - 5, $(this).height() - 5);
        if (flowID == "") flowID = 0;
        gooFlow.setNodeRemarks(remark);
        //新建流程
        gooFlow.onBtnNewClick = function () {
            gooFlow.clearData();
        }
        //保存流程
        gooFlow.onBtnSaveClick = function () {
            var h = gooFlow.$bgDiv.height();
            $("<div class=\"datagrid-mask\"></div>").css({ display: "block", width: "100%", height: h }).appendTo(gooFlow.$bgDiv);
            $("<div class=\"datagrid-mask-msg\"></div>").html("數據正在保存中,請稍候……").appendTo(gooFlow.$bgDiv).css({
                display: "block",
                left: (gooFlow.$bgDiv.width() - 200) / 2,
                top: (h - 45) / 2
            });
            var obj = gooFlow.exportAlter();
            //節點
            var nodeData = "";
            for (var in obj.nodes) {
                var id = gooFlow.$nodeData[i].ID == null ? 0 : gooFlow.$nodeData[i].ID;
                var userID = gooFlow.$nodeData[i].userID == null ? 0 : gooFlow.$nodeData[i].userID;
                nodeData += '{"ID": ' + id + ''
                                     ',"FlowID": ' + flowID + ''
                                     ',"NodeID": "' + i + '"'
                                     ',"UserID": "' + userID + '"'
                                     ',"UserName": "' + gooFlow.$nodeData[i].name + '"'
                                     ',"NodeType":  "' + gooFlow.$nodeData[i].type + '"'
                                     ',"NodeLeft":  ' + gooFlow.$nodeData[i].left + ''
                                     ',"NodeTop":  ' + gooFlow.$nodeData[i].top + ''
                                     ',"NodeWidth":  ' + gooFlow.$nodeData[i].width + ''
                                     ',"NodeHeight":  ' + gooFlow.$nodeData[i].height + ''
                                     ',"Marked": false},';
            }
            if (nodeData != "") {
                nodeData = "[" + $.trimend(nodeData, ',') + "]";
            }
            //連接線
            var lineData = "";
            for (var in obj.lines) {
                var id = gooFlow.$lineData[i].ID == null ? 0 : gooFlow.$lineData[i].ID;
                var conditionID = gooFlow.$lineData[i].conditionID == null ? 0 : gooFlow.$lineData[i].conditionID;
                var lineM = gooFlow.$lineData[i].M == null ? 0 : gooFlow.$lineData[i].M;
                lineData += '{"ID": ' + id + ''
                                  ',"FlowID": ' + flowID + ''
                                     ',"LineID": "' + i + '"'
                                     ',"ConditionID": ' + conditionID + ''
                                     ',"ConditionName": "' + gooFlow.$lineData[i].name + '"'
                                     ',"LineType":  "' + gooFlow.$lineData[i].type + '"'
                                     ',"LineFrom":  "' + gooFlow.$lineData[i].from + '"'
                                     ',"LineTo":  "' + gooFlow.$lineData[i].to + '"'
                                     ',"LineM":  ' + lineM + ''
                                     ',"Marked": false},';
            }
            if (lineData != "") {
                lineData = "[" + $.trimend(lineData, ',') + "]";
            }
            //區域
            var areaData = "";
            for (var in obj.areas) {
                var id = gooFlow.$areaData[i].ID == null ? 0 : gooFlow.$areaData[i].ID;
                areaData += '{"ID": ' + id + ''
                                     ',"FlowID": ' + flowID + ''
                                     ',"AreaID": "' + i + '"'
                                     ',"AreaName":  "' + gooFlow.$areaData[i].name + '"'
                                     ',"AreaLeft":  ' + gooFlow.$areaData[i].left + ''
                                     ',"AreaTop":  ' + gooFlow.$areaData[i].top + ''
                                     ',"AreaWidth":  ' + gooFlow.$areaData[i].width + ''
                                     ',"AreaHeight":  ' + gooFlow.$areaData[i].height + ''
                                     ',"AreaColor":  "' + gooFlow.$areaData[i].color + '"'
                                     ',"Marked": false},';
            }
            if (areaData != "") {
                areaData = "[" + $.trimend(areaData, ',') + "]";
            }
            if (nodeData == "" && lineData == "" && areaData == "") {
                $('.datagrid-mask-msg').remove();
                $('.datagrid-mask').remove();
                return;
            }
            $.ajax({
                type: "post",
                url: "/HR/BacthSave",
                data: { node: nodeData, line: lineData, area: areaData },
                success: function (data) {
                    if (data.status == 1) {
                        jqAlert('保存成功.''info'"reload");
                    }
                    else
                        jqAlert('保存失敗:' + data, 'error')
                    $('.datagrid-mask-msg').remove();
                    $('.datagrid-mask').remove();
                }
            });
        }
        //刷新
        gooFlow.onFreshClick = function () {
            location.reload();
        }
        //單元節點雙擊事件
        gooFlow.$workArea.delegate(".ico + td""dblclick", { inthis: gooFlow }, function (e) {
            var newId = $(this).parents(".GooFlow_item").attr("id");
            var $frame = $("#frame_choose_aud");
            if ($frame.attr("src") == undefined) {
                focusId = newId;
                $frame.attr("src""/HR/BaseFlowChooseEmp");
            }
            else {
                if (focusId != newId) {
                    focusId = newId;
                    window.frames["choose_aud"].initData();
                }
            }
            $("#div_win_choose_aud").window('open');
        });
        //單元連接線雙擊事件
        var tmpClk = "PolyLine";
        if (GooFlow.prototype.useSVG != "")
            tmpClk = "g";
        $(gooFlow.$draw).delegate(tmpClk, "dblclick", { inthis: gooFlow }, function (e) {
            if (GooFlow.prototype.useSVG != "") {
                var $frame = $("#frame_choose_con");
                if ($frame.attr("src") == undefined) {
                    focusId = this.id;
                    $frame.attr("src""/HR/BaseFlowCondition?typeID=" + getUrlParam("typeID"));
                }
                else {
                    if (focusId != this.id) {
                        focusId = this.id;
                        window.frames["choose_con"].unselect();
                    }
                }
                $("#div_win_choose_con").window('open');
            }
        });
        //操作單元刪除事件
        gooFlow.onItemDel = function (id, type) {
            var delItem = gooFlow.getItemInfo(id, type);
            if (delItem.ID != null) {
                uiConfirm("確定要刪除該單元嗎."function () {
                    $.post("/HR/DeleteFlowItem", { "id": id, "type": type }, function (data) {
                        if (data.status == 1) {
                            delItem.ID = null;
                            if (type == "node")
                                gooFlow.delNode(id);
                            else if (type == "line")
                                gooFlow.delLine(id);
                            else if (type == "area")
                                gooFlow.delArea(id);
                            return true;
                        }
                        else
                            jqAlert('刪除失敗:' + data, 'error')
                    });
                });
            }
            else
                return true
        }
        //初始化人員選擇窗體
        showMyWindow($("#div_win_choose_aud"), '選擇人員信息''icon-edit''', 900, 450, true);
        //初始化人員選擇窗體
        showMyWindow($("#div_win_choose_con"), '選擇條件信息''icon-edit''', 900, 450, true);
        //加載數據
        var h = gooFlow.$bgDiv.height();
        $("<div class=\"datagrid-mask\"></div>").css({ display: "block", width: "100%", height: h }).appendTo(gooFlow.$bgDiv);
        $("<div class=\"datagrid-mask-msg\"></div>").html("圖形正在加載中,請稍候……").appendTo(gooFlow.$bgDiv).css({
            display: "block",
            left: (gooFlow.$bgDiv.width() - 200) / 2,
            top: (h - 45) / 2
        });
        var para = { "type""get""url""/HR/LoadWorkArea?flowID=" + flowID, "success": onLoadSuccess, "error": onLoadError };
        gooFlow.loadDataAjax(para);
    });
    function onLoadSuccess(msg) {
        $('.datagrid-mask-msg').remove();
        $('.datagrid-mask').remove();
    }
    function onLoadError(status, errorThrown) {
        $('.datagrid-mask-msg').remove();
        $('.datagrid-mask').remove();
    }
    function backAudChoose(row) {
        gooFlow.setName(focusId, row.user_truename + "(" + row.user_no + ")""node");
        var focusNode = gooFlow.getItemInfo(focusId, "node");
        focusNode.name = row.user_truename + "(" + row.user_no + ")";
        focusNode.userID = row.ID;
        $("#div_win_choose_aud").window('close');
    }
    function backConChoose(row) {
        gooFlow.setName(focusId, row.ConditionName, "line")
        var focusLine = gooFlow.getItemInfo(focusId, "line");
        focusLine.name = row.ConditionName;
        focusLine.conditionID = row.ID;
        $("#div_win_choose_con").window('close');
    }
</script>

  後臺處理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#region BaseFlowPicture
       public ActionResult BaseFlowPicture()
       {
           return View();
       }
       public ActionResult BacthSave(string node = ""string line = ""string area = "")
       {
           try
           {
               if (node != "")
               {
                   List<Q_HR_WorkFlow_Node> nodes = JSONStringToList<Q_HR_WorkFlow_Node>(node);
                   int s = nodes.Where(c => c.NodeType == "start").Count();
                   int e = nodes.Where(c => c.NodeType == "end").Count();
                   if (s != 1)
                       throw new Exception("請設置一個開始節點.");
                   if (e != 1)
                       throw new Exception("請設置一個結束節點.");
                   Q_HR_WorkFlow_NodeManage.BatchSave(nodes);
               }
               if (line != "")
               {
                   List<Q_HR_WorkFlow_Line> lines = JSONStringToList<Q_HR_WorkFlow_Line>(line);
                   Q_HR_WorkFlow_LineManage.BatchSave(lines);
               }
               if (area != "")
               {
                   List<Q_HR_WorkFlow_Area> areas = JSONStringToList<Q_HR_WorkFlow_Area>(area);
                   Q_HR_WorkFlow_AreaManage.BatchSave(areas);
               }
               return Json(new { status = 1 }, JsonRequestBehavior.AllowGet);
           }
           catch (Exception ex)
           {
               return Content(ex.Message);
           }
       }
       public string LoadWorkArea(int flowID = 0)
       {
           DataTable nodes = Q_HR_WorkFlow_NodeManage.GetList(flowID);
           DataTable lines = Q_HR_WorkFlow_LineManage.GetList(flowID);
           IList<Q_HR_WorkFlow_Area> areas = Q_HR_WorkFlow_AreaManage.GetList(flowID);
           string jsonStr = "{";
           string alt;
           //jsonStr += "\"initNum\":" + Q_HR_WorkFlow_NodeManage.GetInitNum() + ",";
           if (nodes.Rows.Count > 0)
           {
               jsonStr += "\"nodes\":{";
               foreach (DataRow row in nodes.Rows)
               {
                   alt = "false";
                   if (row["NodeType"].ToString() == "start" || row["NodeType"].ToString() == "end")
                       alt = "true";
                   jsonStr += "\"" + row["NodeID"] + "\":{"
                           "\"ID\":" + row["ID"] + ""
                           ",\"name\":\"" + row["UserName"] + "(" + row["user_no"] + ")\""
                           ",\"userID\":" + row["UserID"] + ""
                           ",\"type\":\"" + row["NodeType"] + "\""
                           ",\"left\":" + row["NodeLeft"] + ""
                           ",\"top\":" + row["NodeTop"] + ""
                           ",\"width\":" + row["NodeWidth"] + ""
                           ",\"height\":" + row["NodeHeight"] + ""
                           ",\"alt\":" + alt + ""
                           ",\"mark\":" + row["Marked"].ToString().ToLower() + ""
                           "},";
               }
               jsonStr = jsonStr.TrimEnd(',') + "},";
           }
           if (lines.Rows.Count > 0)
           {
               jsonStr += "\"lines\":{";
               foreach (DataRow row in lines.Rows)
               {
                   jsonStr += "\"" + row["LineID"] + "\":{"
                           "\"ID\":" + row["ID"] + ""
                           ",\"name\":\"" + row["ConditionName"] + "\""
                           ",\"conditionID\":" + row["ConditionID"] + ""
                           ",\"type\":\"" + row["LineType"] + "\""
                           ",\"from\":\"" + row["LineFrom"] + "\""
                           ",\"to\":\"" + row["LineTo"] + "\""
                           ",\"M\":" + row["LineM"] + ""
                           ",\"mark\":" + row["Marked"].ToString().ToLower() + ""
                           "},";
               }
               jsonStr = jsonStr.TrimEnd(',') + "},";
           }
           if (areas.Count > 0)
           {
               jsonStr += "\"areas\":{";
               foreach (Q_HR_WorkFlow_Area area in areas)
               {
                   jsonStr += "\"" + area.AreaID + "\":{"
                           "\"ID\":" + area.ID + ""
                           ",\"name\":\"" + area.AreaName + "\""
                           ",\"left\":" + area.AreaLeft + ""
                           ",\"top\":" + area.AreaTop + ""
                           ",\"width\":" + area.AreaWidth + ""
                           ",\"height\":" + area.AreaHeight + ""
                           ",\"color\":\"" + area.AreaColor + "\""
                           "},";
               }
               jsonStr = jsonStr.TrimEnd(',') + "},";
           }
           jsonStr = jsonStr.TrimEnd(',') + "}";
           return jsonStr;
       }
       public ActionResult DeleteFlowItem(string id, string type)
       {
           try
           {
               if (type.Equals("node"))
                   Q_HR_WorkFlow_NodeManage.DeleteFlowNode(id, type);
               else if (type.Equals("line"))
                   Q_HR_WorkFlow_LineManage.DeleteFlowLine(id, type);
               else if (type.Equals("area"))
                   Q_HR_WorkFlow_AreaManage.DeleteFlowArea(id, type);
               return Json(new { status = 1 }, JsonRequestBehavior.AllowGet);
           }
           catch (Exception ex)
           {
               return Content(ex.Message);
           }
       }
       #endregion

  

 

屬性名稱

作用

$id

裝載整個UI的DOM對象的ID。

$bgDiv

最父框架的DIV。

$tool

左側工具欄JQ對象。

$head

頂部欄標題標籤及工具欄按鈕。

$title

載入的流程圖的名稱。

$nodeRemark

左側工具欄中每一種結點或按鈕的說明文字,JSON格式,key爲按鈕類型名,value爲用戶自定義文字說明。

$nowType

當前要繪製的對象類型,開始時爲“cursor”,即不繪製任何元素,只是作爲鼠標指針進行元素選定。

$lineData={}

轉換線數據Map集,以id爲key,value爲詳細數據JSON對象。

$lineCount=0

轉換線數據的數量。

$nodeData={}

節點數據Map集,以id爲key,value爲詳細數據JSON對象。

$nodeCount=0

節點數據的數量。

$areaData={}

分組區數據Map集,以id爲key,value爲詳細數據JSON對象。

$areaCount=0

分組區數據的數量。

$lineDom={}

轉換線DOM展示對象Map集,以id爲key,value爲詳細在DOM對象。

$nodeDom={}

節點JQ展示對象Map集,以id爲key,value爲詳細在JO對象。

$areaDom={}

分組區JQ展示對象Map集,以id爲key,value爲詳細在JO對象。

$max

計算默認ID值的起始SEQUENCE,默認不填時爲1。

$focus

當前被選定的結點/轉換線ID,如果沒選中或者工作區被清空,則爲""。

$cursor

鼠標指針在工作區內的樣式,初始時爲default。

$editable

當前工作區是否可編輯,即是編輯模式還是僅瀏覽模式。

$workArea

裝載結點/線條/分組區域的工作區。

$draw

畫矢量線條的容器,處於工作區中。

$group

僅用來裝配分組區域DOM元素的容器,處於工作區中。

$ghost

專門用在移動、重置大小等操作時,給用戶操作的半透明浮動區。

$textArea

雙擊操作對象後出現的浮動文本域,用來寫重命名方法setName所需的新名稱傳參。

$lineMove

操作移動折線的中段時用到的浮動DIV

$lineOper

選定一條轉換線後出現的浮動操作欄,有改變線的樣式和刪除線等按鈕。

//以下是當初始化的參數property.useOperStack=true且$editable=true時,才存在的屬性:

$undoStack=[]

“撤銷操作”棧。

$redoStack=[]

重做操作棧。

$isUndo

事務操作標誌位,內部調用

$deletedItem={}

在流程圖的編輯操作中被刪除掉的元素ID集合,元素ID爲KEY,元素類型(node,line.area)爲VALUE

 

[GooFlow對象供使用者調用的方法集]

方法名稱

作用

setNodeRemarks(remark)

設定左側工具欄中每一種結點或按鈕的說明文字,傳參是JSON格式,key爲按鈕類型名,value爲用戶自定義文字說明。

switchToolBtn(type)

切換左邊工具欄按鈕,傳參type表示切換成哪種類型的按鈕

addNode(id,json)

增加一個結點,傳參json內容結構與$nodeData的每個屬性單元一樣。

getItemInfo(id,type)

根據id這個KEY,和要獲取的數據類型type(有”node”,”line”,”area”三種取值),返回相應的結點json數據單元

blurItem()

取消所有結點/連線被選定的狀態

focusItem(id,bool)

選定某個結點/轉換線;傳參bool:TRUE決定了要觸發選中事件,FALSE則不觸發選中事件,多用在程序內部調用。

moveNode(id,left,top)

移動一個結點到一個新的位置

setName(id,name,type)

設置結點/連線/分組區域的文字信息;傳參id爲序列,name爲新的名稱,type爲更名對象的數據類型(有”node”,”line”,”area”三種取值)

resizeNode(id,width,height)

重新設置結點的尺寸,開始/結束類型的結點不支持該方法

delNode(id)

刪除結點

setTitle(text)

設置流程圖的名稱

loadData(data)

載入一組數據JSON格式的流程圖數據,傳參data中有title,nodes,lines,areas四個KEY的數據,還有一個可選屬性數據initNum:ID起始序列號最大數字+1——由於繪製的新單元的ID都是按一定序列號及規則自動生成的,爲了防止新載入的數據的ID與編輯時新加入的ID值有重複,將給設計器對象對於新生成單元的ID序列一個新的起始序列號;如果傳參JSON中沒有這個屬性,也可以在調用loadData方法前修改設計器對象的$max屬性值(其實loadData方法執行時會檢查傳參中如果有initNum時,將自動給設計器對象的$max賦上此值);

nodes,lines,areas都爲一組{key:value}式的Map數據,內容結構分別與GooFlow對象屬性中的$nodeData,$lineData,$areaData一致.

loadDataAjax(para)

用AJAX方式,遠程讀取一組數據;

參數para爲JSON結構,與JQUERY中$.ajax()方法的傳參一樣

需要後臺異步返回JSON格式的msg結果,其內容格式與loadData方法的傳參一樣。

exportData()

把畫好的結束導出到一個本函數返回的變量中(其實也可以直接訪問GooFlow對象的$nodeData,$lineData,$areaData這三個JSON屬性)

exportAlter()

//只把本次編輯流程圖中作了變更(包括增刪改)的元素導出到一個變量中,以方便用戶每次編輯載入的流程圖後只獲取變更過的數據

transNewId(oldId,newId,type)

變更元素的ID,一般用於快速保存後,將後臺返回新元素的ID更新到頁面中;type爲元素類型(節點,連線,區塊)

clearData()

清空工作區及已載入的數據

destrory()

銷燬自己

addLine(id,json)

增加一條線,傳參json內容結構與$lineData的每個屬性單元一樣。

setLineType(id,newType)

重新設置連線的樣式. 傳參newType的取值有:"sl"直線, "lr"中段可左右移動型折線, "tb"中段可上下移動型折線

setLineM(id,M)

設置折線中段的X座標值(可左右移動時)或Y座標值(可上下移動時);直線不支持此方法

delLine(id)

刪除轉換線

markItem(id,type,mark)

//用顏色標註/取消標註一個結點或轉換線,常用於顯示重點或流程的進度。

       //這是一個在編輯模式中無用,但是在純瀏覽模式中非常有用的方法,實際運用中可用於跟蹤流程的進度。

//傳參:id是操作單元對象唯一序列號;type是操作單元類型(“node”或者”line”,分組區域不支持此方法);mark爲布爾值,表示是否標註/取消標註某個ID值的數據單元對象

addArea(id,json)

增加一個分組區域,傳參json內容結構與$areaData的每個屬性單元一樣。

moveArea(id,left,top)

移動分組區域到新的位置上.

delArea(id)

刪除分組區域

setAreaColor(id,color)

設置分組區域的顏色,傳參color爲顏色樣式,只有”red”,”yellow”,”blue”,”green”四種取值

resizeArea(id,width,height)

重新設置區分組區域的尺寸

      

reinitSize(width,height)

重構整個流程圖設計器的寬高,在瀏覽器窗口大小改變或者父容器寬高改變時,執行這個方法能讓設計器重新適應新的寬高顯示。

//以下是當初始化的參數property.useOperStack=true時,才存在的方法:

pushOper(funcName,paras)

僅供內部方法調用的方法:把對工作區內的數據單元編輯操作(增/刪/改/重命名/移動/標註等)加入整條管理棧中,好進入撤銷/重做的控制;

注意:將爲了節省瀏覽器內存空間,undo/redo中的操作緩存棧,最多隻可放40步操作;超過40步時,將自動刪掉最舊的一個緩存。

pushExternalOper

(func,jsonPara)

//將外部的方法加入到GooFlow對象的事務操作堆棧中,在過後的undo/redo操作中可以進行控制,一般用於對流程圖以外的附加信息進行編輯的事務撤銷/重做控制;

//傳參func爲要執行方法對象,jsonPara爲外部方法僅有的一個面向字面的JSON傳參或者數據,由JSON對象或數組帶入所有要傳的信息;

//提示:爲了讓外部方法能夠被UNDO/REDO,需要在編寫這些外部方法實現時,加入對該方法執行後效果回退的另一個執行方法的pushExternalOper。

undo()

撤銷最近一次操作

redo()

重做最近一次被撤銷的操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章