Port loaded from itemArray doesn't show correctly

I am serializing my ports on a node and would like to read them back through item array. However, the first port is not showing correctly. Only the first one though. Any idea? Thanks in advance.

One more thing I realize, if I take out itemTemplate and make it to be under my nodeTemplete directly, I will lose my four default ports made by makePort function but the layout of loaded ports is correct then…

nodeTemplate

// add ports
this.makePort(“T”, new go.Spot(0.5, 0.0, -2.25, 0.0), go.Spot.Top, true, true, false, false),
this.makePort(“L”, go.Spot.Left, go.Spot.Left, true, true, false, false),
this.makePort(“R”, new go.Spot(1.0, 0.5, -4.5, 0.0), go.Spot.Right, true, true, false, false),
this.makePort(“B”, new go.Spot(0.5, 1.0, -2.25, 0.0), go.Spot.Bottom, true, true, false, false),
this.$(go.Panel, “Spot”,
new go.Binding(“itemArray”, “portArray”),
{
desiredSize: NodeSizes.SHAPE_SIZE_IRREGULAR,
itemTemplate: this.makeAdditionalPort(true, true, false, false)
}
)

private makePort = (name: string, alignmentSpot: go.Spot, anchorSpot: go.Spot, output: boolean, input: boolean, fromDup: boolean, toDup: boolean) => {
// the port is basically just a small transparent square
return this.$(go.Shape, “Square”,
{
fill: null,
stroke: null,
strokeWidth: 0.5,
desiredSize: new go.Size(8, 8),
alignment: alignmentSpot, // align the port on the main Shape
alignmentFocus: alignmentSpot, // just inside the Shape
portId: name, // declare this object to be a “port”
fromSpot: anchorSpot,
toSpot: anchorSpot, // declare where links may connect at this port
fromLinkable: output,
toLinkable: input, // declare whether the user may draw links to/from here
cursor: “pointer”, // show a different cursor to indicate potential link point
fromLinkableDuplicates: fromDup,
toLinkableDuplicates: toDup,
fromMaxLinks: 1 // only allow one ingoing connector per anchor point
});
}

private makeAdditionalPort = (output: boolean, input: boolean, fromDup: boolean, toDup: boolean) => {
// the port is basically just a small transparent square
return this.$(go.Panel,
new go.Binding(“portId”, “portId”),
new go.Binding(“fromSpot”, “fromSpot”, go.Spot.parse),
new go.Binding(“toSpot”, “toSpot”, go.Spot.parse),
new go.Binding(“alignment”, “alignment”, go.Spot.parse),
new go.Binding(“alignmentFocus”, “alignmentFocus”, go.Spot.parse),
{
fromLinkable: output,
toLinkable: input, // declare whether the user may draw links to/from here
fromLinkableDuplicates: fromDup,
toLinkableDuplicates: toDup,
fromMaxLinks: 1 // only allow one ingoing connector per anchor point,
},
this.$(go.Shape, “Square”,
{
// fill: null,
// stroke: null,
fill: “#ffffff”,
stroke: “#717171”,
strokeWidth: 0.5,
desiredSize: new go.Size(8, 8),
cursor: “pointer”, // show a different cursor to indicate potential link point

            })
    );
}

“portArray”: [
{
“portId”: “T2”,
“alignment”: “0.25 0 -2.25 0”,
“alignmentFocus”: “0.25 0 -2.25 0”,
“fromSpot”: “0.5 0 0 0”,
“toSpot”: “0.5 0 0 0”
},
{
“portId”: “T3”,
“alignment”: “0.75 0 -2.25 0”,
“alignmentFocus”: “0.75 0 -2.25 0”,
“fromSpot”: “0.5 0 0 0”,
“toSpot”: “0.5 0 0 0”
},
{
“portId”: “B2”,
“alignment”: “0.25 1 -2.25 0”,
“alignmentFocus”: “0.25 1 -2.25 0”,
“fromSpot”: “0.5 1 0 0”,
“toSpot”: “0.5 1 0 0”
},
{
“portId”: “B3”,
“alignment”: “0.75 1 -2.25 0”,
“alignmentFocus”: “0.75 1 -2.25 0”,
“fromSpot”: “0.5 1 0 0”,
“toSpot”: “0.5 1 0 0”
},
{
“portId”: “L2”,
“alignment”: “0 0.25 0 0”,
“alignmentFocus”: “0 0.25 0 0”,
“fromSpot”: “0 0.5 0 0”,
“toSpot”: “0 0.5 0 0”
},
{
“portId”: “L3”,
“alignment”: “0 0.75 0 0”,
“alignmentFocus”: “0 0.75 0 0”,
“fromSpot”: “0 0.5 0 0”,
“toSpot”: “0 0.5 0 0”
},
{
“portId”: “R2”,
“alignment”: “1 0.25 -4.5 0”,
“alignmentFocus”: “1 0.25 -4.5 0”,
“fromSpot”: “1 0.5 0 0”,
“toSpot”: “1 0.5 0 0”
},
{
“portId”: “R3”,
“alignment”: “1 0.75 -4.5 0”,
“alignmentFocus”: “1 0.75 -4.5 0”,
“fromSpot”: “1 0.5 0 0”,
“toSpot”: “1 0.5 0 0”
}
]

The Spot Panel must always have a main element, which defaults to the first element, about which the rest of the elements are aligned.

But it appears that all of your Spot Panel elements are ports.

I see. But if I put that ports panel under my node template directly, I will then lose all my default ports generated by makePort. How does it happen then?

Now, what I stored in itemtemplate is loaded correctly but the makeport’s port will be disappeared.

            this.makePort("T", new go.Spot(0.5, 0.0, -2.25, 0.0), go.Spot.Top, true, true, false, false),
            this.makePort("L", go.Spot.Left, go.Spot.Left, true, true, false, false),
            this.makePort("R", new go.Spot(1.0, 0.5, -4.5, 0.0), go.Spot.Right, true, true, false, false),
            this.makePort("B", new go.Spot(0.5, 1.0, -2.25, 0.0), go.Spot.Bottom, true, true, false, false),
            //this.$(go.Panel, "Spot",
                new go.Binding("itemArray", "portArray"),
                {
                    //desiredSize: NodeSizes.SHAPE_SIZE_IRREGULAR,
                    itemTemplate: this.makeAdditionalPort(true, true, false, false)
                }
            //)

The best and most general solution, if you want to have a variable number of ports, is to put them all in the Array that is the value of data.portArray. The first element of the SpotPanel would just be the main body – the Panel holding the blue rectangle, icon, and text.