jQWidgets Forums
jQuery UI Widgets › Forums › Grid › Testing Event Listeners when dynamically changing grid columns
Tagged: angular grid, detach, DOM, Dynamic Columns, event, Event Listeners, grid, jquery grid, jqxgrid
This topic contains 1 reply, has 2 voices, and was last updated by Dimitar 9 years, 9 months ago.
-
Author
-
Hi,
I was doing some tests as I need a way how to change columns dynamically and yet I found that there is a demo ready to use.
As I am working on a personal SPA, I wanted to be sure that the grid will keep events at its lowest and no memory leaks come up (including any detached elements in dom tree).
Attached below I have an example of a test with changes in source and changes in columns dynamically (which the latter is tested via destroying the grid or just changing the columns via jqxGrid({ columns: columns });
I want to know if there is any bugs related to the grid internal elements which once being removed from the dom, their events are also being removed or not (without the need to destroy the grid), as from the test I made, when I use jqxGrid({ columns: columns }), the listeners count keeps growing instead of keeping the same amount of listeners, and when I destroy the grid and reset all (as in the below test), the listeners count also resets to the amount started.
Can you please tell me what you think about this? And also let me know if I am doing something wrong due to this thing.
<!DOCTYPE html>
<html lang=”en”>
<head>
<title id=’Description’>The Grid’s columns and rows in this examples are retrieved from JSON file.</title>
<link rel=”stylesheet” href=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/styles/jqx.base.css” type=”text/css” />
<script type=”text/javascript” src=”http://code.jquery.com/jquery-1.11.3.min.js”></script>
<script type=”text/javascript” src=”http://underscorejs.org/underscore-min.js”></script>
<script type=”text/javascript” src=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxcore.js”></script>
<script type=”text/javascript” src=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxbuttons.js”></script>
<script type=”text/javascript” src=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxscrollbar.js”></script>
<script type=”text/javascript” src=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxmenu.js”></script>
<script type=”text/javascript” src=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.js”></script>
<script type=”text/javascript” src=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.selection.js”></script>
<script type=”text/javascript” src=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.columnsresize.js”></script>
<script type=”text/javascript” src=”http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxdata.js”></script>
<script>
var testData = [
{
“columns”: [
{
“text”: “ID”,
“datafield”: “id”,
“width”: “30”
},
{
“text”: “Name”,
“datafield”: “name”,
“width”: “250”
},
{
“text”: “Beverage Type”,
“datafield”: “type”,
“width”: “250”
},
{
“text”: “Calories”,
“datafield”: “calories”,
“width”: “180”
},
{
“text”: “Total Fat”,
“datafield”: “totalfat”,
“width”: “120”
},
{
“text”: “Protein”,
“datafield”: “protein”
}
]
},
{
“rows”: [
{
“id”: “1”,
“name”: “Hot Chocolate”,
“type”: “Chocolate Beverage”,
“calories”: “370”,
“totalfat”: “16g”,
“protein”: “14g”
},
{
“id”: 2,
“name”: “Peppermint Hot Chocolate”,
“type”: “Chocolate Beverage”,
“calories”: “440”,
“totalfat”: “16g”,
“protein”: “13g”
},
{
“id”: “3”,
“name”: “Salted Caramel Hot Chocolate”,
“type”: “Chocolate Beverage”,
“calories”: “450”,
“totalfat”: “16g”,
“protein”: “13g”
},
{
“id”: “4”,
“name”: “White Hot Chocolate”,
“type”: “Chocolate Beverage”,
“calories”: “420”,
“totalfat”: “16g”,
“protein”: “12g”
},
{
“id”: “5”,
“name”: “Caffe Americano”,
“type”: “Espresso Beverage”,
“calories”: “15”,
“totalfat”: “0g”,
“protein”: “1g”
},
{
“id”: “6”,
“name”: “Caffe Latte”,
“type”: “Espresso Beverage”,
“calories”: “190”,
“totalfat”: “7g”,
“protein”: “12g”
},
{
“id”: “7”,
“name”: “Caffe Mocha”,
“type”: “Espresso Beverage”,
“calories”: “330”,
“totalfat”: “15g”,
“protein”: “13g”
},
{
“id”: “8”,
“name”: “Cappuccino”,
“type”: “Espresso Beverage”,
“calories”: “120”,
“totalfat”: “4g”,
“protein”: “8g”
},
{
“id”: “9”,
“name”: “Caramel Brulee Latte”,
“type”: “Espresso Beverage”,
“calories”: “420”,
“totalfat”: “9g”,
“protein”: “8g”
},
{
“id”: “10”,
“name”: “Caramel Macchiato”,
“type”: “Espresso Beverage”,
“calories”: “240”,
“totalfat”: “11g”,
“protein”: “10g”
},
{
“id”: “11”,
“name”: “Peppermint Hot Chocolate”,
“type”: “Espresso Beverage”,
“calories”: “440”,
“totalfat”: “10g”,
“protein”: “13g”
},
{
“id”: “12”,
“name”: “Cinnamon Dolce Latte”,
“type”: “Espresso Beverage”,
“calories”: “260”,
“totalfat”: “6g”,
“protein”: “10g”
},
{
“id”: “13”,
“name”: “Eggnog Latte”,
“type”: “Espresso Beverage”,
“calories”: “460”,
“totalfat”: “16g”,
“protein”: “13g”
},
{
“id”: “14”,
“name”: “Espresso”,
“type”: “Espresso Beverage”,
“calories”: “5”,
“totalfat”: “1g”,
“protein”: “1g”
},
{
“id”: “15”,
“name”: “Espresso Con Panna”,
“type”: “Espresso Beverage”,
“calories”: “30”,
“totalfat”: “1g”,
“protein”: “0g”
},
{
“id”: “16”,
“name”: “Espresso Macchiato”,
“type”: “Espresso Beverage”,
“calories”: “100”,
“totalfat”: “1g”,
“protein”: “0g”
},
{
“id”: “17”,
“name”: “Flavored Latte”,
“type”: “Espresso Beverage”,
“calories”: “250”,
“totalfat”: “6g”,
“protein”: “12g”
},
{
“id”: “18”,
“name”: “Gingerbread Latte”,
“type”: “Espresso Beverage”,
“calories”: “320”,
“totalfat”: “13g”,
“protein”: “12g”
},
{
“id”: “19”,
“name”: “White Chocolate Mocha”,
“type”: “Espresso Beverage”,
“calories”: “470”,
“totalfat”: “18g”,
“protein”: “15g”
},
{
“id”: 20,
“name”: “Skinny Peppermint Mocha”,
“type”: “Espresso Beverage”,
“calories”: 130,
“totalfat”: “15g”,
“protein”: “13g”
},
{
“id”: “21”,
“name”: “Skinny Flavored Latte”,
“type”: “Espresso Beverage”,
“calories”: “120”,
“totalfat”: “0g”,
“protein”: “12g”
},
{
“id”: “22”,
“name”: “Pumpkin Spice Latte”,
“type”: “Espresso Beverage”,
“calories”: “380”,
“totalfat”: “13g”,
“protein”: “14g”
},
{
“id”: “23”,
“name”: “Caffe Vanilla Frappuccino”,
“type”: “Frappuccino Blended Beverage”,
“calories”: “310”,
“totalfat”: “3g”,
“protein”: “3g”
},
{
“id”: “24”,
“name”: “Caffe Vanilla Frappuccino Light”,
“type”: “Frappuccino Blended Beverage”,
“calories”: “180”,
“totalfat”: “0g”,
“protein”: “3g”
},
{
“id”: “25”,
“name”: “Caramel Brulee Frappuccino”,
“type”: “Frappuccino Blended Beverage”,
“calories”: “410”,
“totalfat”: “13g”,
“protein”: “4g”
},
{
“id”: “26”,
“name”: “Caramel Brulee Frappuccino Light”,
“type”: “Frappuccino Blended Beverage”,
“calories”: “190”,
“totalfat”: “0g”,
“protein”: “3g”
},
{
“id”: “27”,
“name”: “Eggnog Frappuccino”,
“type”: “Frappuccino Blended Beverage”,
“calories”: “420”,
“totalfat”: “18g”,
“protein”: “7g”
},
{
“id”: “28”,
“name”: “Mocha Frappuccino”,
“type”: “Frappuccino Blended Beverage”,
“calories”: “400”,
“totalfat”: “15g”,
“protein”: “5g”
},
{
“id”: “29”,
“name”: “Tazo Green Tea Creme Frappuccino”,
“type”: “Frappuccino Blended Beverage”,
“calories”: “430”,
“totalfat”: “16g”,
“protein”: “6g”
}
]
}
];var gridAdapter = ”;
var destroyBeforeChange = false;$(document).ready(function () {
var source = {
localdata: testData,
datatype: “json”
};$(“#jqxgrid”).jqxGrid({
width: 850,
columnsresize: true
});reset();
});var getRandomData = function (data, amountToGet, alwaysInclude) {
var arr = [];if (!amountToGet)
amountToGet = data.length / 2;while (arr.length < amountToGet) {
var randomnumber = Math.ceil(Math.random() * data.length);var found = false;
for (var i = 0; i < arr.length; i++) {
if (arr[i] == data[randomnumber – 1]) {
found = true;
break;
}
}if (!found) arr[arr.length] = data[randomnumber – 1];
}if (alwaysInclude && alwaysInclude.length) {
_.each(alwaysInclude, function (item, index) {
var itemInArray = _.findWhere(arr, { ‘datafield’: item });if (_.isEmpty(itemInArray)) {
var itemInData = _.findWhere(data, { ‘datafield’: item });arr.push(itemInData);
}
});
}return arr;
}var first = true;
var reset = function (onlyColumns) {
var columns = getRandomData(testData[0].columns, 4, [‘id’]);
var rows = getRandomData(testData[1].rows);if (first) {
gridAdapter = new $.jqx.dataAdapter({
datafields: [
{ name: ‘id’, type: ‘number’ },
{ name: ‘name’, type: ‘string’ },
{ name: ‘type’, type: ‘string’ },
{ name: ‘calories’, type: ‘int’ },
{ name: ‘totalfat’, type: ‘string’ },
{ name: ‘protein’, type: ‘string’ }
],
id: ‘id’,
localdata: rows
}, {
autoBind: true
});$(“#jqxgrid”).jqxGrid(‘beginupdate’, true);
$(“#jqxgrid”).jqxGrid({
source: gridAdapter,
columns: columns
});
$(“#jqxgrid”).jqxGrid(‘endupdate’);
}
else {
if (onlyColumns) {
var dataToUpdate = {
source: gridAdapter,
columns: columns
};if (destroyBeforeChange) {
$(“#jqxgrid”).jqxGrid(‘destroy’);$(‘body’).prepend(‘<div id=”jqxgrid”></div>’);
}
else
delete dataToUpdate.source;$(“#jqxgrid”).jqxGrid(dataToUpdate);
}
else {
gridAdapter._source.localdata = rows;
$(“#jqxgrid”).jqxGrid(‘updatebounddata’, ‘cells’);
}
}console.log(‘listenersCount: ‘, listenerCount);
first = false;
}var listenerCount = 0;
(function () {
var ael = Node.prototype.addEventListener;
Node.prototype.addEventListener = function () {
listenerCount++;
ael.apply(this, arguments);
}
var rel = Node.prototype.removeEventListener;
Node.prototype.removeEventListener = function () {
listenerCount–;
rel.apply(this, arguments);
}
})();
</script>
</head>
<body class=’default’>
<div id=”jqxgrid”></div>
<input type=”button” onclick=”reset()” value=”Set Different Source Data” />
<input type=”button” onclick=”reset(true)” value=”Set Different Columns” />
</body>
</html>Hi Stephen Agius,
Thank you for your feedback. We will investigate this behaviour.
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/ -
AuthorPosts
You must be logged in to reply to this topic.