数据绑定是一种从源对象提取值并在目标对象上设置属性的方法。目标对象通常是GraphObject;源对象通常是模型中保存的JavaScript数据对象。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc"), // get the Node.location from the data.loc value $(go.Shape, "RoundedRectangle", { fill: "white" }, new go.Binding("fill", "color")), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); var nodeDataArray = [ // for each node specify the location using Point values { key: "Alpha", color: "lightblue", loc: new go.Point(0, 0) }, { key: "Beta", color: "pink", loc: new go.Point(100, 50) } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
转换功能
Point类包含静态函数Point.parse,您可以使用该函数 将字符串转换为Point对象。它期望输入字符串中有两个数字,分别代表Point.x和Point.y值。它返回具有这些值的Point对象。
您可以将转换函数作为第三个参数传递给Binding构造函数。在这种情况下,它是Point.parse。这允许以字符串(“ 100 50”)的形式而不是作为返回Point的表达式来指定位置。对于模型对象的数据属性,您通常会希望使用字符串来表示 Point,Size,Rect,Margin和Spot。而不是对这些类的对象的引用。字符串很容易用JSON和XML读写。尝试读取/写入对象类将占用额外的空间,并且需要编写者和阅读者双方进行额外的合作。
new go.Binding('location','loc',go.Point.parse), var nodeDataArray=[ { key: "Alpha", color: "lightblue" , loc: '-100 20'}, { key: "Beta", color: "pink" , loc: '100 20' } ]
转换函数可以是命名函数或匿名函数。它们采用数据属性值,并返回适合所设置属性的值。它们不应有任何副作用。他们可能以任意顺序被多次调用。
这一个示例,其中有多个Shape属性数据绑定到同一个名为“ highlight”的布尔数据属性。每个转换函数都采用布尔值,并为数据绑定的属性返回适当的值。通过将“ highlight”数据属性设置为false或true,从数据控制每个节点的外观变得很简单。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { // default values if the data.highlight is undefined: fill: "yellow", stroke: "orange", strokeWidth: 2 }, new go.Binding("fill", "highlight", function(v) { return v ? "pink" : "lightblue"; }), new go.Binding("stroke", "highlight", function(v) { return v ? "red" : "blue"; }), new go.Binding("strokeWidth", "highlight", function(v) { return v ? 3 : 1; })), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); var nodeDataArray = [ { key: "Alpha", loc: "0 0", highlight: false }, { key: "Beta", loc: "100 50", highlight: true }, { key: "Gamma", loc: "0 100" } // highlight property undefined: use defaults ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
改变图结构
数据绑定不用于建立零件之间的关系。对于特定模型知道的数据属性,例如GraphLinksModel中的链接数据的“到”或“从” ,必须调用适当的模型方法才能修改数据属性。直接修改数据属性而不调用适当的模型方法可能会导致不一致或不确定的行为。
对于节点数据,模型方法是 Model.setCategoryForNodeData, Model.setKeyForNodeData, GraphLinksModel.setGroupKeyForNodeData, TreeModel.setParentKeyForNodeData和 TreeModel.setParentLinkCategoryForNodeData。对于链接数据,模型方法为 GraphLinksModel.setCategoryForLinkData, GraphLinksModel.setFromKeyForLinkData, GraphLinksModel.setFromPortIdForLinkData, GraphLinksModel.setToKeyForLinkData, GraphLinksModel.setToPortIdForLinkData和 GraphLinksModel.setLabelKeysForLinkData。
本示例更改链接数据的“ to”属性,使链接连接到其他节点。本示例使用默认的链接模板,该模板没有任何数据绑定。链接关系的更改是通过调用模型方法而不是通过数据绑定来完成的。
双向绑定的原因
在可设置的属性上 使用双向绑定的基本原因是确保对该属性的任何更改都将复制到相应的模型数据中。通过确保模型是最新的,您只需保存模型即可轻松地“保存图”,而“加载图”仅是将模型加载到内存中并设置Diagram.model的问题。如果您仅在模型数据中保留JSON可序列化的数据,则可以使用Model.toJson 和Model.fromJson方法在模型与文本表示之间进行转换。
大多数绑定不需要是TwoWay。 出于性能原因,除非您确实需要将更改传播回数据,否则不应将Binding设为TwoWay。大多数可设置的属性仅在初始化时设置,然后永不更改。
可设置属性仅在某些代码对其进行设置时才更改值。该代码可能在您作为应用程序一部分编写的代码中。或者它可能在命令(请参阅Commands)或工具(请参阅Tools)中。这是一个可能存在TwoWay绑定的属性列表,因为预定义的命令或工具之一对其进行了修改:
- Part.location,通过DraggingTool如果已启用
- Link.points,通过LinkReshapingTool(如果已启用)
- GraphObject.desiredSize,由ResizingTool启用(如果已启用)
- GraphObject.angle,由RotatingTool启用(如果已启用)
- TextBlock.text,如果已启用,则由TextEditingTool进行
- Part.isSelected,通过许多工具和命令
- Node.isTreeExpanded和Node.wasTreeExpanded,通过CommandHandler.collapseTree和CommandHandler.expandTree,由“TreeExpanderButton”之称
- Group.isSubGraphExpanded和Group.wasSubGraphExpanded,通过CommandHandler.collapseSubGraph和CommandHandler.expandSubGraph,由“SubGraphExpanderButton”之称
如果修改属性的工具无法运行,或者修改属性的命令无法调用,则无需在属性上使用TwoWay绑定。除非编写代码来修改它们,否则您可能不需要任何其他属性上的TwoWay绑定。即使这样,有时还是最好通过直接调用Model.setDataProperty来编写代码来修改模型数据,这取决于OneWay绑定来更新GraphObject属性。
如果源是GraphObject而不是模型数据,也可以使用TwoWay绑定。当您不希望将状态存储在模型中,但是您想要在同一零件中同步GraphObjects的属性时,则不需要那么频繁地使用它。 谨慎使用TwoWay绑定。