流程图控件GoJS教程:变更事件
GoJS是一款功能强大,快速且轻量级的流程图控件,可帮助你在JavaScript 和HTML5 Canvas程序中创建流程图,且极大地简化您的JavaScript / Canvas 程序。
GoJS现已更新至最新版本2.0.16发布,修复了一些bug,增强用户体验,赶快下载试试吧~
变更事件
GoJS生成 三种基本类型的事件: DiagramEvent,InputEvent和ChangedEvent。本页讨论后者,它们是在修改Diagram,GraphObject, Model或Model数据对象时生成的。
GoJS中的ChangedEvent是状态更改的通知,主要是对象属性更改。ChangedEvent记录发生的更改的种类以及足以撤消和重做的足够信息。
更改的事件由Model和Diagram产生。他们是多播事件,所以你可以调用Model.addChangedListener和Diagram.addChangedListener,以及相应的removeChangedListener方法。为了方便起见,您还可以在图上指定模型更改侦听器:Diagram.addModelChangedListener。 ChangedEvent通过模型更改侦听收到旨意有一个非空值ChangedEvent.model。同样,图更改侦听器收到的ChangedEvents的ChangedEvent.diagram值将为非null 。
一图总是将自身注册为它的一个侦听模式,以便它可以自动的通知更改模型并相应地更新它的零件。此外,UndoManager(如果启用)会自动侦听对模型和图的更改,以便它可以记录更改历史记录并执行撤消和重做。
型号和数据变更
模型属性更改
Model ChangedEvents记录状态更改到模型中的数据或模型本身。通过调用Model.setDataProperty和Model属性设置器来生成模型的ChangedEvents。
对于特性的变化,该信息包括所述ChangedEvent.object被修改,则ChangedEvent.propertyName和ChangedEvent.oldValue和ChangedEvent.newValue该属性的值。属性更改由ChangedEvent.change属性值为ChangedEvent,Property标识。
一些更改代表模型的结构更改,而不仅仅是简单的模型数据更改。“结构”更改是模型负责维护的关系的插入,修改或删除。在这种情况下,ChangedEvent.modelChange属性将是一个非空字符串,用于命名更改的类型。Property ChangedEvent的以下名称对应于结构模型数据的更改:
替换Model.nodeDataArray数组后为“ nodeDataArray ”
“ nodeCategory ”改为Model.setCategoryForNodeData
“ nodeGroupKey ”改为GraphLinksModel.setGroupKeyForNodeData
替换了GraphLinksModel.linkDataArray数组后的“ linkDataArray ”
“ linkFromKey ”改为由于调用了GraphLinksModel.setFromKeyForLinkData
“ linkToKey ”改为GraphLinksModel.setToKeyForLinkData
“ linkFromPortId ”改为GraphLinksModel.setFromPortIdForLinkData
“ linkToPortId ”改为GraphLinksModel.setToPortIdForLinkData
“ linkLabelKeys ”改为GraphLinksModel.setLabelKeysForLinkData
“ linkCategory ”改为GraphLinksModel.setCategoryForLinkData
“ nodeParentKey ”改为TreeModel.setParentKeyForNodeData
“ parentLinkCategory ”改为TreeModel.setParentLinkCategoryForNodeData
ChangedEvent.modelChange的值将是以下字符串之一。ChangedEvent.propertyName的值取决于已修改的实际数据属性的名称。例如,对于模型属性更改“ linkFromKey”,实际属性名称默认为“ from”。但是您可能通过将GraphLinksModel.linkFromKeyProperty设置为其他一些数据属性名称来使用其他属性名称。
通过调用Model.setDataProperty,可以在节点数据或链接数据对象上更改任何属性。这样的调用将导致属性名称记录为ChangedEvent.propertyName。这些情况被视为常规属性更改,而不是结构模型更改,因此ChangedEvent.modelChange将为空字符串。当然,ChangedEvent.object的值将是已修改的JavaScript对象。
某些更改可能是暂时发生的,因为某些代码(例如在Tool中)可能希望出于其自身目的使用临时对象。但是,您的更改侦听器可能对此类ChangedEvent不感兴趣。如果是这样的话,你可能要忽略ChangedEvent如果Model.skipsUndoManager(或Diagram.skipsUndoManager)为真。
最后,模型本身也会发生属性更改。有关此类属性的列表,请参见Model,GraphLinksModel和TreeModel的文档。这些情况也被视为常规属性更改,因此ChangedEvent.modelChange将为空字符串。无论ChangedEvent.model和ChangedEvent.object将是模型本身。
模型集合变更
其他类型的更改事件包括ChangedEvent,Insert和ChangedEvent,Remove。除了用于记录属性更改的所有前面提到的ChangedEvent属性之外,ChangedEvent.oldParam和ChangedEvent.newParam还提供了能够正确撤消和重做更改所需的“索引”信息。
Insert和Remove ChangedEvent的以下名称对应于对集合的模型更改:
“ nodeDataArray ”改为Model.addNodeData或Model.removeNodeData
“ linkDataArray ”改为GraphLinksModel.addLinkData或GraphLinksModel.removeLinkData
“ linkLabelKeys ”改为GraphLinksModel.addLabelKeyForLinkData 或GraphLinksModel.removeLabelKeyForLinkData
交易次数
模型更改事件的最后一种类型是ChangedEvent,Transaction。这些并不是严格意义上的对象更改,但它们确实会通知事务何时开始或完成,或者撤消或重做何时开始或完成。
ChangedEvent.propertyName 的以下值描述了刚刚发生的与事务相关的事件的类型:
“ StartingFirstTransaction ”
“ StartedTransaction ”
“ CommittingTransaction ”
“ CommittedTransaction ”
“ RolledBackTransaction ”
“ 开始撤消 ”
“ 完成撤消 ”
“ 起始重做 ”
“ 完成重做 ”
在每种情况下,ChangedEvent.object是持有一系列ChangedEvent的Transaction。该ChangedEvent.oldValue是事务的名字-传递给串UndoManager.startTransaction或UndoManager.commitTransaction。执行交易的各种标准命令和工具记录了他们采用的交易名称。但是您的代码可以使用任意数量的事务名称。
通常,不应在任何事务ChangedEvent的侦听器中对模型或其任何数据进行任何更改。
交易完成后保存模型
事务完成后,通常想更新服务器数据库。使用ChangedEvent.isTransactionFinished只读属性可检测到这种情况。您将需要实现一个Changed侦听器,如下所示:
// notice whenever a transaction or undo/redo has occurred
diagram.addModelChangedListener(function(evt) { if (evt.isTransactionFinished) saveModel(evt.model);
});
Transaction.changes的值将是ChangedEvent的List,按记录顺序。这些ChangedEvents表示对Model以及对Diagram或其GraphObject的更改。型号会有变化e.model !== null; 图表会有变化e.diagram !== null。
逐步保存对模型的更改
如果您不想在每个事务结束时保存整个模型,而只希望对模型进行某些更改,则可以遍历更改列表以选择您要关注的更改。例如,这是一个侦听器,仅当将节点数据添加到Model.nodeDataArray或从Model.nodeDataArray删除时,才记录消息。
diagram.addModelChangedListener(function(evt) { // ignore unimportant Transaction events
if (!evt.isTransactionFinished) return; var txn = evt.object; // a Transaction
if (txn === null) return; // iterate over all of the actual ChangedEvents of the Transaction
txn.changes.each(function(e) { // ignore any kind of change other than adding/removing a node
if (e.modelChange !== "nodeDataArray") return; // record node insertions and removals
if (e.change === go.ChangedEvent.Insert) { console.log(evt.propertyName + " added node with key: " + e.newValue.key);
} else if (e.change === go.ChangedEvent.Remove) { console.log(evt.propertyName + " removed node with key: " + e.oldValue.key);
}
});
});
当用户添加节点(包括通过复制)并删除节点时,上述侦听器将发出消息。事务事件的ChangedEvent.propertyName(即上面的代码中的evt)将为“ CommittedTransaction”,“ FinishedUndo”或“ FinishedRedo”。请注意,删除节点的“ FinishedUndo”实际上是在添加该节点,就像撤消插入节点的操作实际上是将其删除一样。
类似地,以下是一个示例,当连接,重新连接或断开链接时发出通知。这不仅检查GraphLinksModel.linkDataArray的插入和删除,还更改链接数据的“ from”和“ to”属性。
diagram.addModelChangedListener(function(evt) { // ignore unimportant Transaction events
if (!evt.isTransactionFinished) return; var txn = evt.object; // a Transaction
if (txn === null) return; // iterate over all of the actual ChangedEvents of the Transaction
txn.changes.each(function(e) { // record node insertions and removals
if (e.change === go.ChangedEvent.Property) { if (e.modelChange === "linkFromKey") { console.log(evt.propertyName + " changed From key of link: " +
e.object + " from: " + e.oldValue + " to: " + e.newValue);
} else if (e.modelChange === "linkToKey") { console.log(evt.propertyName + " changed To key of link: " +
e.object + " from: " + e.oldValue + " to: " + e.newValue);
}
} else if (e.change === go.ChangedEvent.Insert && e.modelChange === "linkDataArray") { console.log(evt.propertyName + " added link: " + e.newValue);
} else if (e.change === go.ChangedEvent.Remove && e.modelChange === "linkDataArray") { console.log(evt.propertyName + " removed link: " + e.oldValue);
}
});
});
注意:上面的代码仅适用于GraphLinksModel,其中链接数据是单独的JavaScript对象。
查看更新演示,以演示如何在提交事务或完成撤消或重做操作时跟踪模型的更改。常见的模式是遍历当前事务的ChangedEvents,以便决定在数据库中记录什么。
图表和GraphObject的更改
Diagram ChangedEvents记录状态更改为图表中的GraphObject或RowColumnDefinition,或图表中的图层,或图表本身。对于此类事件,ChangedEvent.diagram将为非null。
图的大多数ChangedEvents都会记录属性更改,例如某些代码设置了TextBlock.text属性或Part.location属性时。在某些地方会生成ChangedEvents来记录对集合的插入或删除,例如Panel.insertAt。对于ChangedEvent.Transaction的图,永远不会有任何ChangedEvents。
尽管图表的ChangedEvents对于撤消/重做对于保持视觉逼真度很重要,但是在保存模型时通常会忽略它们。仅模型的ChangedEvents会将状态更改记录到模型数据。因此,要保存到数据库,您将只考虑那些ChangedEvent.model 不为null的ChangedEvent。
=====================================================
想要购买GoJS正版授权的朋友可以。
更多精彩内容,欢迎关注下方的微信公众号,及时获取产品最新资讯▼▼▼