流程圖控件GoJS教程:變更次數(shù)和UndoManager
GoJS是一款功能強(qiáng)大,快速且輕量級的流程圖控件,可幫助你在JavaScript 和HTML5 Canvas程序中創(chuàng)建流程圖,且極大地簡化您的JavaScript / Canvas 程序。
GoJS現(xiàn)已更新至最新版本2.0.16發(fā)布,修復(fù)了一些bug,增強(qiáng)用戶體驗(yàn),趕快下載試試吧~
GoJS模型和圖表利用UndoManager來記錄所有更改,并支持撤消和重做這些更改。每個狀態(tài)更改都記錄在ChangedEvent中,該事件包含有關(guān)前后的足夠信息,以便能夠在向后(撤消)或向前(重做)任一方向上重現(xiàn)狀態(tài)變化。將此類更改組合到Transaction中,以便可以將可能導(dǎo)致許多更改的用戶操作撤消并作為單個操作重做。
并非所有狀態(tài)更改都會導(dǎo)致ChangedEvent,UndoManager可以記錄該更改。一些屬性被認(rèn)為是瞬態(tài)的,例如Diagram.position,Diagram.scale, Diagram.currentTool,Diagram.currentCursor或Diagram.isModified。一些變化是結(jié)構(gòu)性的或認(rèn)為是不變的,如Diagram.model,的任何屬性CommandHandler,或任何工具或布局屬性。但是,當(dāng)屬性值已更改時,大多數(shù)GraphObject和模型屬性確實(shí)會分別在圖或模型上引發(fā)ChangedEvent。
交易次數(shù)
每當(dāng)您響應(yīng)某些事件以編程方式修改模型或其數(shù)據(jù)時,都應(yīng)將代碼包裝在事務(wù)中。呼叫Diagram.startTransaction或Model.startTransaction,進(jìn)行更改,然后調(diào)用Diagram.commitTransaction或Model.commitTransaction。盡管使用事務(wù)的主要好處是將撤消/重做的副作用歸為一組,但是即使您的應(yīng)用程序不支持用戶的撤消/重做,也應(yīng)使用事務(wù)。
與數(shù)據(jù)庫事務(wù)一樣,您將需要執(zhí)行短暫且不頻繁的事務(wù)。不要讓用戶操作之間的事務(wù)繼續(xù)進(jìn)行。考慮在循環(huán)中使用單個事務(wù)是否比在循環(huán)中重復(fù)啟動和結(jié)束事務(wù)更好。不要在屬性設(shè)置器中執(zhí)行事務(wù)-這樣的粒度太小。而是執(zhí)行一個事務(wù),在該事務(wù)中設(shè)置屬性以響應(yīng)某些用戶操作或外部事件。
但是,與數(shù)據(jù)庫事務(wù)不同,您無需進(jìn)行事務(wù)即可訪問任何狀態(tài)。所有JavaScript對象都在內(nèi)存中,因此您可以隨時查看它們的屬性。但是,當(dāng)您想要對圖表或GraphObject或模型中的模型或JavaScript對象進(jìn)行狀態(tài)更改時,請在事務(wù)中進(jìn)行。
唯一的例外是,在將模型分配給Diagram.model之前初始化模型時,不需要進(jìn)行事務(wù)處理。(圖只能通過Model的Model.undoManager屬性訪問UndoManager 。)
此外,在由Tool或CommandHandler命令執(zhí)行的事務(wù)中已經(jīng)執(zhí)行了許多事件處理程序和偵聽器,因此您通常不需要在此類函數(shù)中啟動和提交事務(wù)。閱讀API文檔以獲取有關(guān)是否在事務(wù)中調(diào)用函數(shù)的詳細(xì)信息。例如,將GraphObject.click設(shè)置為事件處理程序以響應(yīng)對對象的單擊,如果該對象想要修改模型或圖表,則需要執(zhí)行事務(wù)。大多數(shù)自定義單擊事件處理程序不會更改圖表,而是會更新一些HTML。
但實(shí)施的“ExternalObjectsDropped” DiagramEvent聽眾,通常不希望修改在剛剛落下零件Diagram.selection,在內(nèi)部調(diào)用DraggingTool的交易,所以不需要額外的開始/提交需要的事務(wù)呼叫。
最后,某些自定義項(xiàng)(例如Node.linkValidation謂詞)完全不應(yīng)修改圖或模型。
僅當(dāng)模型的UndoManager.isEnabled設(shè)置為true時, 模型更改和圖表更改才會記錄在UndoManager中。
為了更好地理解內(nèi)存中對象和事務(wù)之間的關(guān)系,請查看以下圖:
使用事務(wù)的典型情況是某些命令對模型進(jìn)行了更改。
// define a function named "addChild" that is invoked by a button click addChild = function() { var selnode = diagram.selection.first(); if (!(selnode instanceof go.Node)) return; diagram.commit(function(d) { // have the Model add a new node data var newnode = { key: "N" }; d.model.addNodeData(newnode); // this makes sure the key is unique // and then add a link data connecting the original node with the new one var newlink = { from: selnode.data.key, to: newnode.key }; // add the new link to the model d.model.addLinkData(newlink); }, "add node and link"); }; diagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, "RoundedRectangle", { fill: "whitesmoke" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.layout = $(go.TreeLayout); var nodeDataArray = [ { key: "Alpha" }, { key: "Beta" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray); diagram.model.undoManager.isEnabled = true;
在以下示例中,選擇一個節(jié)點(diǎn),然后單擊按鈕。addChild函數(shù)添加將所選節(jié)點(diǎn)連接到新節(jié)點(diǎn)的鏈接。如果未選擇任何節(jié)點(diǎn),則不會發(fā)生任何事情。
支持UndoManager
對JavaScript數(shù)據(jù)屬性的更改不會自動導(dǎo)致可觀察到的任何通知。因此,當(dāng)您想要以可以撤消和重做的方式更改屬性的值時,應(yīng)調(diào)用Model.setDataProperty。這將獲取該屬性的先前值,將該屬性設(shè)置為新值,然后調(diào)用Model.raiseDataChanged,這還將自動更新Node中與數(shù)據(jù)相對應(yīng)的任何目標(biāo)綁定。
diagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, "RoundedRectangle", { fill: "whitesmoke" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "someValue")) // bind to the "someValue" data property ); var nodeDataArray = [ { key: "Alpha", someValue: 1 } ]; diagram.model = new go.GraphLinksModel(nodeDataArray); diagram.model.undoManager.isEnabled = true; // define a function named "incrementData" callable by onclick incrementData = function() { diagram.model.commit(function(m) { var data = m.nodeDataArray[0]; // get the first node data m.set(data, "someValue", data.someValue + 1); }, "increment"); };
移動節(jié)點(diǎn)。單擊按鈕以增加第一個節(jié)點(diǎn)數(shù)據(jù)上的“ someValue”屬性的值。單擊以聚焦在圖中,然后按Ctrl-Z和Ctrl-Y撤消和重做移動和值更改。
=====================================================
想要購買GoJS正版授權(quán)的朋友可以咨詢慧都官方客服。
更多精彩內(nèi)容,歡迎關(guān)注下方的微信公眾號,及時獲取產(chǎn)品最新資訊▼▼▼