Ext version tested:
  • Ext 3.3.0

Adapter used:
  • ext

Description:
When a GridPanel has a store and a column model which columns and fields are not exactly the same (not the same number, or not in the same order for example), and the GridPanel also has an ActionColumn, the ActionColumn may be rendered incorrectly. For example, it may be rendered with a dirty mark when another column is modified.

In fact, the problem is not limited to ActionColumn, it concerns any column of which the dataIndex is undefined.

Debugging already done:
I have found that the problem originates from the GridView getColumnData method. Here's some code that exposes the faulty behaviour:
Code:
var grid = new Ext.grid.GridPanel({
    store: new Ext.data.JsonStore({
        fields: ["col1","col2"]
    })
    ,columns: [
        {dataIndex: "col2", id: "col2"}
        ,{xtype: "actioncolumn", id: "actionCol"}
    ]
    ,renderTo: Ext.getBody()
});

var cols = grid.getView().getColumnData(), c0 = cols[0], c1 = cols[1];

alert("name: " + c1.name + "\nid: " + c1.id);
// name: col2
// id: actionCol
This code shows clearly that the getColumnData method mistakenly associates the name of another column to the data of the ActionColumn. This wrong name is then used in other methods of GridView, and that explains how information regarding another column can be rendered into the ActionColumn.

The problem itself is that, when it finds a column in the column model of which the dataIndex is undefined, the getColumnData method tries to guess it from the index of the field in the grid's store. Here's the incriminated piece of code (found in Ext 3.3.0 ext-all-debug.js, at line 47164):
Code:
columns[i] = {
    name    : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined),
    //...
};
I don't understand why it does that, and that is furthermore a very wild guess since the columns in the column model and the fields in the data store have no real reasons to be in the same order...

Possible fix:
Since I don't know why the aforementioned method tries to guess the name this way, I prefer to avoid overriding it directly. The following code snippet fixes the problem with ActionColumn by preventing its dataIndex from being undefined (put it anywhere after Ext script files). It could easily be adapted for another class of column, if needed...
Code:
// Prevents ActionColumn from being rendered according to meta associated with another column
(function() {
	var uber = Ext.grid.ActionColumn.prototype.constructor;
	Ext.grid.ActionColumn.prototype.constructor = function() {
		uber.apply(this, arguments);
		if (this.dataIndex === undefined) this.dataIndex = null;
	};
})();