Weird behavior when having multiple grids in the same page

2 posts, 0 answers
  1. Azzlack
    Azzlack avatar
    5 posts
    Member since:
    Feb 2011

    Posted 25 Sep 2015 Link to this post

    I have 7 grids on a tabbed page using AngularJS. My setup worked fine as of verson 2015.1.429, but after trying an upgrade to 2015.2.x I experience some really odd behavior.

    First, none of the grids show up, even though the read() method on the datasource runs. Secondly, one of the grids doesn't stop making requests after receiving a 204 from the server.

    001.scope.expenseGridOptions = {
    002.    dataSource: new kendo.data.DataSource({
    003.        type: "odata",
    004.        transport: {
    005.            read: function (options) {
    006.                scope.working = true;
    007. 
    008.                var odataParams = ODataFactory.mapParameters(options.data);
    009. 
    010.                // Override orderby property alias
    011.                if (odataParams.$orderby) {
    012.                    odataParams.$orderby = odataParams.$orderby.replace(/\/title/, '/Title');
    013.                }
    014. 
    015.                ExpenseService.queryProjectExpenses($stateParams.id, odataParams).then(function (result) {
    016.                    scope.working = false;
    017. 
    018.                    if (result && result.value) {
    019.                        // Make sure all items have Invoice field
    020.                        _.each(result.value, function(item) {
    021.                            if (!item.Invoice) {
    022.                                item.Invoice = {};
    023.                            }
    024.                        });
    025. 
    026.                        options.success(result);
    027.                    } else {
    028.                        options.success({});
    029.                    }
    030.                });
    031.            }
    032.        },
    033.        schema: {
    034.            data: function(data) {
    035.                return data.value;
    036.            },
    037.            total: function(data) {
    038.                return data["@odata.count"];
    039.            },
    040.            model: {
    041.                id: "Id",
    042.                fields: {
    043.                    Id: { type: "number", editable: false, nullable: true },
    044.                    Created: { type: "date" },
    045.                    Date: { type: "date" },
    046.                    UserId: { type: "string", from: "Creator.value" },
    047.                    UserName: { type: "string", from: "Creator.title" },
    048.                    Cost: { type: "number" },
    049.                    SalePrice: { type: "number" },
    050.                    InvoicedAmount: { type: "number" },
    051.                    Title: { type: "string" },
    052.                    Description: { type: "string" },
    053.                    Approved: { type: "boolean" },
    054.                    Processed: { type: "boolean" },
    055.                    CompanyId: { type: "string", from: "Company.value" },
    056.                    CompanyName: { type: "string", from: "Company.title" },
    057.                    ProjectId: { type: "string", from: "Project.value" },
    058.                    ProjectName: { type: "string", from: "Project.title" }
    059.                }
    060.            }
    061.        },
    062.        pageSize: 200,
    063.        serverPaging: true,
    064.        serverFiltering: true,
    065.        serverSorting: true,
    066.        aggregate: [
    067.            { field: "Cost", aggregate: "sum" },
    068.            { field: "SalePrice", aggregate: "sum" },
    069.            { field: "InvoicedAmount", aggregate: "sum" }
    070.        ],
    071.        sort: { field: "Date", dir: "desc" }
    072.    }),
    073.    columns: [
    074.        {
    075.            field: "Id",
    076.            title: "Id",
    077.            hidden: true
    078.        },
    079.        {
    080.            field: "Date",
    081.            title: "Date",
    082.            type: "date",
    083.            template: "#= moment(Date).format('LL') #",
    084.            aggregates: ["count"],
    085.            footerTemplate: "TOTAL",
    086.            groupHeaderTemplate: "#= moment(value).format('LL') # | Count: #= count #",
    087.            groupFooterTemplate: "SUBTOTAL"
    088.        },
    089.        {
    090.            field: "Title",
    091.            title: "Title",
    092.            groupable: false
    093.        },
    094.        {
    095.            field: "Description",
    096.            title: "Description",
    097.            groupable: false,
    098.            template: function(dataItem) {
    099.                return "<small>" + (dataItem.Description || "") + "</small>";
    100.            }
    101.        },
    102.        {
    103.            field: "Cost",
    104.            title: "Cost",
    105.            aggregates: ["sum"],
    106.            groupable: false,
    107.            template: function(dataItem) {
    108.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(dataItem.Cost).format('0,0.00') + "</span></div>";
    109.            },
    110.            groupFooterTemplate: function(data) {
    111.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(data.Cost.sum).format('0,0.00') + "</span></div>";
    112.            },
    113.            footerTemplate: function(data) {
    114.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(data.Cost.sum).format('0,0.00') + "</span></div>";
    115.            }
    116.        },
    117.        {
    118.            field: "SalePrice",
    119.            title: "Sale Price",
    120.            aggregates: ["sum"],
    121.            groupable: false,
    122.            template: function(dataItem) {
    123.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(dataItem.SalePrice).format('0,0.00') + "</span></div>";
    124.            },
    125.            groupFooterTemplate: function(data) {
    126.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(data.SalePrice.sum).format('0,0.00') + "</span></div>";
    127.            },
    128.            footerTemplate: function(data) {
    129.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(data.SalePrice.sum).format('0,0.00') + "</span></div>";
    130.            }
    131.        },
    132.        {
    133.            field: "InvoicedAmount",
    134.            title: "Invoiced Amount",
    135.            aggregates: ["sum"],
    136.            groupable: false,
    137.            template: function(dataItem) {
    138.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(dataItem.InvoicedAmount).format('0,0.00') + "</span></div>";
    139.            },
    140.            groupFooterTemplate: function(data) {
    141.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(data.InvoicedAmount.sum).format('0,0.00') + "</span></div>";
    142.            },
    143.            footerTemplate: function(data) {
    144.                return "<div><span style='display:inline-block;width:25%;text-align:left'>" + numeral.languageData().currency.symbol + "</span><span style='display:inline-block;width:75%;text-align:right;white-space:nowrap;'>" + numeral(data.InvoicedAmount.sum).format('0,0.00') + "</span></div>";
    145.            }
    146.        },
    147.        {
    148.            field: "CompanyName",
    149.            title: "Company",
    150.            aggregates: ["count"],
    151.            groupHeaderTemplate: "#= value # | Count: #= count #",
    152.            template: function(dataItem) {
    153.                return "<a href='' ui-sref='customers.details({ id: \"" + dataItem.CompanyId + "\" })' ui-sref-opts='{ title: \"" + AttributeSanitizerFactory.escape(dataItem.CompanyName) + "\" }'>" + dataItem.CompanyName + "</a>";
    154.            }
    155.        },
    156.        {
    157.            field: "Processed",
    158.            title: "Processed",
    159.            aggregates: ["count"],
    160.            groupHeaderTemplate: function(data) {
    161.                if (data.value === true) {
    162.                    return "<i class='fa fa-check'></i> | Count: " + data.count;
    163.                }
    164. 
    165.                return " | Count: " + data.count;
    166.            },
    167.            template: function(dataItem) {
    168.                if (dataItem.Processed === true) {
    169.                    return "<i class='fa fa-check' style='display:block;text-align:center'></i>";
    170.                }
    171. 
    172.                return "";
    173.            }
    174.        },
    175.        {
    176.            field: "Invoiced",
    177.            title: "Invoiced",
    178.            aggregates: ["count"],
    179.            groupHeaderTemplate: function(data) {
    180.                if (data.value === true) {
    181.                    return "<i class='fa fa-check'></i> | Count: " + data.count;
    182.                }
    183. 
    184.                return " | Count: " + data.count;
    185.            },
    186.            template: function(dataItem) {
    187.                if (dataItem.Invoiced === true) {
    188.                    return "<i class='fa fa-check' style='display:block;text-align:center'></i>";
    189.                }
    190. 
    191.                return "";
    192.            }
    193.        },
    194.        {
    195.            command: [
    196.                {
    197.                    className: "edit",
    198.                    name: "edit",
    199.                    text: "<i class='fa fa-pencil'></i>",
    200.                    click: editExpense
    201.                }, {
    202.                    className: "delete",
    203.                    name: "delete",
    204.                    text: "<i class='fa fa-trash-o'></i>",
    205.                    click: deleteExpense
    206.                }
    207.            ],
    208.            title: " ",
    209.            width: 60
    210.        }
    211.    ],
    212.    pageable: {
    213.        info: true,
    214.        numeric: false,
    215.        previousNext: true
    216.    },
    217.    groupable: {
    218.        showFooter: true
    219.    },
    220.    scrollable: false,
    221.    sortable: true,
    222.    resizable: true,
    223.    filterable: false,
    224.    dataBound: function(e) {
    225.        var data = this._data;
    226. 
    227.        for (var x = 0; x < data.length; x++) {
    228.            var dataItem = data[x];
    229.            var tr = $(this.wrapper).find("[data-uid='" + dataItem.uid + "']");
    230. 
    231.            if (dataItem.Processed) {
    232.                tr.find('a.k-grid-edit').remove();
    233.                tr.find('a.k-grid-delete').remove();
    234.            }
    235.        }
    236.    }
    237.};

    Every grid uses the same setup, only difference are the api endpoints and column setup.

    This was tried with version 2015.2.624, 2015.2.​805, 2015.2.902. I've downgraded again to 2015.1.429 as everything works fine there.

     

    Have anyone experienced anything similar? I cannot find anything in the release notes for the non-working versions that changes something fundamental about Grid and DataSource.

  2. Dimo
    Admin
    Dimo avatar
    8331 posts

    Posted 30 Sep 2015 Link to this post

    Hi Azzlack,

    For Q2 2015, we removed a timeout that we were using to initialize Kendo UI widgets in Angular scenarios. The lack of this timeout may be related to the observed behavior. The way it was implemented, the timeout caused performance issues and was not a good practice in general.

    Unfortunately, I am not able to provide specific suggestions, based on the provided Grid settings only.

    Here is a test page, which works as expected. Please compare with your implementation.

    http://dojo.telerik.com/uDOyI

    One thing that you can try is wrap the Grid options definition in a $timeout like this:

    $timeout(function(){
       scope.expenseGridOptions = {
          // ...
       };
    });


    Let me know if you have any questions. In such case it may be useful to modify my above example, so that the discussed issue is exhibited and send it back, so that we can inspect it and get a better idea of your scenario.

    Regards,
    Dimo
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Kendo UI is VS 2017 Ready
Back to Top