流程图控件GoJS教程:变更事件

GoJS是一款功能强大,快速且轻量级的流程图控件。本教程将为您介绍变更事件的内容。

GoJS是一款功能强大,快速且轻量级的流程图控件,可帮助你在JavaScript 和HTML5 Canvas程序中创建流程图,且极大地简化您的JavaScript / Canvas 程序。

GoJS现已更新至最新版本2.0.16发布,修复了一些bug,增强用户体验,赶快下载试试吧~

GoJS最新试用版

变更事件

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正版授权的朋友可以咨询官方客服

更多精彩内容,欢迎关注下方的微信公众号,及时获取产品最新资讯▼▼▼

标签:

来源:慧都

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年9月11日
下一篇 2019年9月11日

相关推荐

发表回复

登录后才能评论