View Full Version : [CLOSED] ImageCommandColumn prepareCommand fires twice

Feb 16, 2015, 4:59 PM
Below is a scaled down version of GridPanel -> Commands -> Prepare_Commands (http://examples2.ext.net/#/GridPanel/Commands/Prepare_Commands/). I placed a debugger in the javascript fn prepareCommand. There are two data rows, but the function fires four times.

I can see that the call stack is different the second time through, but I am not sure what to make of it.

<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
if (!X.IsAjaxRequest)
this.Store1.DataSource = new object[]
new object[] { "3m Co", 71.72, 0.02, 0.03, "9/1 12:00am" },
new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, "9/1 12:00am" },

<!DOCTYPE html>

<head runat="server">
<title>Prepare Commands - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />

//in PrepareCommand we can modify command
var prepareCommand = function (grid, command, record, row) {
<form runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />

<ext:Store ID="Store1" runat="server">
<ext:Model runat="server">
<ext:ModelField Name="company" />
<ext:ModelField Name="price" Type="Float" />
<ext:ModelField Name="change" Type="Float" />
<ext:ModelField Name="pctChange" Type="Float" />
<ext:ModelField Name="lastChange" Type="Date" DateFormat="M/d hh:mmtt" />

Title="Row commands"
<ColumnModel runat="server">
<ext:Column runat="server" Text="Company" DataIndex="company" Flex="1" />
<ext:Column runat="server" Text="Price" Width="100" DataIndex="price">
<Renderer Format="UsMoney" />
<ext:Column runat="server" Text="Change" Width="75" DataIndex="change" />
<ext:Column runat="server" Text="Change" Width="75" DataIndex="pctChange" />
<ext:DateColumn runat="server" Text="Last Updated" Width="85" DataIndex="lastChange" />

<ext:ImageCommandColumn runat="server" Width="100" Text="Image Cmds">
<ext:ImageCommand Icon="Delete" CommandName="Delete" ToolTip-Text="Delete" />
<PrepareCommand Fn="prepareCommand" />
<Command Handler="Ext.Msg.alert(command, record.data.company);" />
<ext:RowSelectionModel runat="server" Mode="Single" />

Feb 16, 2015, 5:04 PM
it's gonna be fired to each row. That's how it is supposed to work.

Take a look on the following example: http://examples.ext.net/#/GridPanel/Commands/Prepare_Toolbar/

Feb 16, 2015, 5:20 PM
Ok I will take a look, but there are only two rows in the grid panel and only one command per row, but it fires four times. Twice for each row.

Fire #1 - Delete command, Row 0
Fire #2 - Delete command, Row 1

Fire #3 - Delete command, Row 0
Fire #4 - Delete command, Row 1

If you look at the stack trace during the debug you can see it is different the second time around.

Feb 16, 2015, 5:38 PM
Cris, i replaced your prepareCommand by the following:

//in PrepareCommand we can modify command
var prepareCommand = function (grid, command, record, row) {
window.console.log(Ext.String.format("prepareCommand - {0}", new Date()));

and prepareCommand was fired just twice, as shown bellow:


In addition, i would like to aware you that prepareCommand is gonna be fired for each row if you sort, if you call gridInstance.getView().refresh(), and from these on.

Feb 16, 2015, 5:51 PM
I will try it against the latest v2 trunk to see if a patch was applied. I am current running against Rev 5968 [Sept 17, 2014].

Feb 17, 2015, 9:06 PM

Anyway to find a patch for v2. I downloaded the latest revision for v2 (6340 - Feb 12, 2015) and the issue still exists. Ext.NET v3 no longer has the issue.

Feb 17, 2015, 11:19 PM
Hello, Chris Wolcott!

I hope you don't mind me replying while you asked for @Daniil's reponse but I think I can offer a good piece of advice here.

Last year I went under this same issue while dealing with grid renderers. It seems the layout builder may render the cell in a two-step approach, what makes these double-calling every render event.

For you to have control over it, you may choose to run your action either in the grid's componentLayoutCounter first or second step. It is represented by a 1 or 2 (possibly more) depending on the number of steps.

So, if you just change your JS function to this (assuming you want to do your action in the first step), you'll be done.

var prepareCommand = function (grid, command, record, row) {
if (grid.componentLayoutCounter == 1) console.log("fire " + fireCnt++);

I found and discussed this issue on this thread (http://forums.ext.net/showthread.php?46681).

Hope this helps! Let us know if it doesn't.

Feb 18, 2015, 1:24 AM
No I don't mind. It is just habit that I am use to working with Daniil.

So in the example above the code below worked fine. Basically skipping the code when grid.componentLayoutCounter == 1.

var prepareCommand = function (grid, command, record, row) {
if (grid.componentLayoutCounter == 1) return;
if (command.command == 'Delete' && record.get("price") < 50) {
command.hidden = true;
command.hideMode = 'display'; //you can try 'visibility' also

When I added it to my code it still performed double the calls. When I checked the counter the values are 2 and 3, never 1. So if I don't want it to be called twice I could skip when 2 and process when 3. So in my case will it always be 2 and 3 or sometimes 1 and 2? I obviously want to process when it is the last time.

Nothing breaks with it being called twice, but as a developer I like to understand why.

So is there no patch/override for v2, since v3 is working properly. Did v3 change architecture that fixed the issue.

Feb 18, 2015, 6:30 AM
Yes, there is a defect in ExtJS 4 / Ext.NET 2. A GridPanel is being rendered twice on initial load with a Store's AutoLoad="true" (that is by default). There was a quite comprehensive discussion in the forums regarding this problem, but I could not find.

As a solution you could try a DeferRowRender="false" setting on the GridPanel. Though, to be honest, I am not sure it is safe.

As an alternative solution (and stable for sure) you could set
AutoLoad="false" for the Store and this for the GridPanel:

<ViewReady Handler="this.getStore().load();" />

Feb 18, 2015, 10:51 AM
Exactly what I needed. I used the AutoLoad="false" and added the Listener ViewReady.

Please close the thread.