How to trigger AJAX call on dropping object from palette to diagram?

The code above should not be causing a Palette refresh, and the Palette should be initialized properly since the model is being set.

Something else must be going on. Are you able to send us a link to your code or reproduce the problem on codepen.io?

The complete GoJS code is here:

function initMacro() {
    var $ = go.GraphObject.make;

    var myDiagram =
        $(go.Diagram, "myDiagramDiv",
        {
            allowDrop: true,
            "undoManager.isEnabled": true
        });

    myDiagram.requestUpdate();

    myDiagram.nodeTemplateMap.add("",
        $(go.Node, go.Panel.Auto,
            new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
            $(go.Shape,
                { figure: "Rectangle", fill: "white", strokeWidth: 2 },
                new go.Binding("stroke", "color"),
                { portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" }),
            $(go.TextBlock,
                {
                    maxSize: new go.Size(150, NaN),
                    textAlign: "center",
                    margin: 6,
                    editable: true,
                    name: "TEXT",
                    font: "11pt Helvetica, Arial, sans-serif"
                },
                new go.Binding("text", "text").makeTwoWay())));

    myDiagram.nodeTemplateMap.add("element",
        $(go.Node, go.Panel.Auto,
            new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
            $(go.Shape,
                { figure: "Rectangle", fill: "white", strokeWidth: 2 },
                new go.Binding("stroke", "color"),
                { portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" }),
            $(go.TextBlock,
                {
                    maxSize: new go.Size(50, 50),
                    textAlign: "center",
                    margin: 6,
                    editable: true,
                    name: "TEXT",
                    font: "11pt Helvetica, Arial, sans-serif"
                },
                new go.Binding("text", "text").makeTwoWay())));

    myDiagram.nodeTemplateMap.add("circle",
        $(go.Node, go.Panel.Auto,
            { movable: true },
            new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
            $(go.Shape,
            { figure: "Circle", fill: "white", desiredSize: new go.Size(40, 40), strokeWidth: 2 }, new go.Binding("stroke", "color"),
            { portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" }),
            $(go.TextBlock,
                {
                    maxSize: new go.Size(18, 18),
                    textAlign: "center",
                    margin: 6,
                    editable: false,
                    name: "TEXT",
                    font: "11pt Helvetica, Arial, sans-serif"
                },
                new go.Binding("text", "text").makeTwoWay()))
    );

    myDiagram.nodeTemplateMap.add("object1",
        $(go.Node, go.Panel.Auto,
            new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
            $(go.Shape,
                { figure: "Rectangle", fill: "white", desiredSize: new go.Size(40, 30), strokeWidth: 2 }, new go.Binding("stroke", "color"),
                new go.Binding("stroke", "color"),
                { portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" }),
            $(go.TextBlock,
                {
                    maxSize: new go.Size(40, 40),
                    textAlign: "center",
                    margin: 6,
                    editable: false,
                    name: "TEXT",
                    font: "11pt Helvetica, Arial, sans-serif"
                },
                new go.Binding("text", "text").makeTwoWay())));

    var tableNode = $(go.Node, go.Panel.Auto,
        $(go.Shape, { fill: "white", stroke: "gray", strokeWidth: 3 }),
        { movable: true },
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        $(go.Panel, "Table",
            new go.Binding("itemArray", "properties"),
            {
                defaultAlignment: go.Spot.Left,
                defaultColumnSeparatorStroke: "black",
                itemTemplate:
                    $(go.Panel, "TableRow",
                        $(go.TextBlock, new go.Binding("text", "property_name"),
                        { column: 0, margin: 2, font: "bold 10pt sans-serif" }),
                        $(go.TextBlock, new go.Binding("text", "property_value"),
                        { column: 1, margin: 2 })
                    )
            },
            $(go.Panel, "TableRow",
                { isPanelMain: true },
                $(go.TextBlock, "Name",
                { column: 0, margin: new go.Margin(2, 2, 0, 2), font: "bold 10pt sans-serif" }),
                $(go.TextBlock, "Value",
                { column: 1, margin: new go.Margin(2, 2, 0, 2), font: "bold 10pt sans-serif" })
            ),
            $(go.RowColumnDefinition,
            { row: 0, background: "lightgray" }),
            $(go.RowColumnDefinition,
            { row: 1, separatorStroke: "black" })
        )
    );

    myDiagram.nodeTemplateMap.add("table", tableNode);

    myDiagram.groupTemplate =
        $(go.Group, go.Panel.Auto,
            {
                isSubGraphExpanded: false,
                ungroupable: true
            },
            new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
            $(go.Shape,
                { figure: "Rectangle", fill: "white", strokeWidth: 2 },
                new go.Binding("stroke", "color"),
                { portId: "" }),
            $(go.TextBlock,
                {
                    maxSize: new go.Size(50, 50),
                    textAlign: "center",
                    margin: 6,
                    editable: true,
                    name: "TEXT",
                    font: "11pt Helvetica, Arial, sans-serif"
                },
                new go.Binding("text", "text").makeTwoWay()));

    myDiagram.linkTemplate =
        $(go.Link,
            $(go.Shape, { strokeWidth: 1.5 }));

    var myPalette =
        $(go.Palette, "myPaletteDiv",
        {
            nodeTemplateMap: myDiagram.nodeTemplateMap,
            groupTemplateMap: myDiagram.groupTemplateMap
        });

    myDiagram.addDiagramListener("ExternalObjectsDropped", function (e) {
        if (myDiagram.currentTool instanceof go.TextEditingTool) {
            myDiagram.currentTool.acceptText(go.TextEditingTool.LostFocus);
        }
        myDiagram.commandHandler.ungroupSelection();
        jQuery.ajax({
            type: "GET",
            url: '/Home/GetRandomObjectProperties'
        }).done(function (data) {
            if (e.parameter.selection.first()) {
                myPalette.model = new go.GraphLinksModel([
                    { key: "B", text: "block B", color: "black" },
                    { key: "C", text: "block C", color: "black" },
                    { key: "G", text: "Macro1", isGroup: true },
                    { key: "D", text: "Macro2", isGroup: true },
                    { category: "circle", key: "Gc", text: "A", color: "black", group: "G", loc: "0 0" },
                    {
                        category: "table", key: "Ga", group: "G", loc: "60 0",
                        properties: data.map(function (item) {
                            return { "property_name": item.Item1.toString(), "property_value": item.Item2.toString() };
                        })
                    },
                    { category: "object1", key: "Gd", text: "AAAA", color: "black", group: "D", loc: "0 0" },
                    {
                        category: "table", key: "Ge", group: "D", loc: "60 0",
                        properties: data.map(function (item) {
                            return { "property_name": item.Item1.toString(), "property_value": item.Item2.toString() };
                        })
                    }
                ], []);
            }
        });
    });

    myPalette.model = new go.GraphLinksModel([
        { key: "B", text: "block B", color: "black" },
        { key: "C", text: "block C", color: "black" },
        { key: "G", text: "Macro1", isGroup: true },
        { key: "D", text: "Macro2", isGroup: true },
        { category: "circle", key: "Gc", text: "A", color: "black", group: "G", loc: "0 0" },
        {
            category: "table", key: "Ga", group: "G", loc: "60 0"
        },
        { category: "object1", key: "Gd", text: "AAAA", color: "black", group: "D", loc: "0 0" },
        {
            category: "table", key: "Ge", group: "D", loc: "60 0"
        }
    ], []);
}

The diagram look as following:

The data we get from MVC action are random and they are not important. The palette refreshing when we drop any element to diagram area.

Your “done” function is replacing the Palette’s model, which is causing the Palette to be reinitialized. So do not set Palette.model.

Instead set only the “properties” property of the newly created node data object in the main Diagram by calling myDiagram.model.setDataProperty(myDiagram.model.findNodeDataForKey(...), "properties", ...data...) within a transaction.

The code looks as following now:

jQuery.ajax({
    type: "GET",
    url: '/Home/GetRandomObjectProperties'
}).done(function (data) {
    if (e.parameter.selection.first()) {
        var nodedata = myDiagram.selection.first().data;
        var properties = data.map(function (item) {
            return { "property_name": item.Item1.toString(), "property_value": item.Item2.toString() };
        });
        myDiagram.model.setDataProperty(nodedata, "properties", properties);
    }
});

And as a result no more palette refreshing, but there is no data on macros elements.

Also, how can I check if node is group or not?

Rather than myDiagram.selection.first(), you can iterate the selection to find the node of the category you want. You want to find the table node, not the group, since ungroupSelection will destroy it the “Macro1” group upon dropping it.

Try something like this:

jQuery.ajax({
    type: "GET",
    url: '/Home/GetRandomObjectProperties'
}).done(function (data) {
    // loop through selection to find table node and populate properties
    myDiagram.selection.each(function (p) {
        if (p instanceof go.Node && p.category === "table") {
            var nodedata = p.data;
            var properties = data.map(function (item) {
                return { "property_name": item.Item1.toString(), "property_value": item.Item2.toString() };
            });
            myDiagram.model.setDataProperty(nodedata, "properties", properties);
            return;
        }
    }
});

Rather than searching through the diagram or through the model, in the “ExternalObjectsDropped” listener you should find the key of the new node data object that should hold your properties table information.

That’s why above I wrote:

myDiagram.model.setDataProperty(myDiagram.model.findNodeDataForKey(...), "properties", ...data...)

where the argument to Model.findNodeDataForKey should have been found by looking at the newly ungrouped nodes when the macro was expanded. Somehow you will need to know which node is which – I couldn’t answer that because only you know what your macro expands to.