ExtJS personal ‘how-to’ notes


ExtJS is a great JavaScript framework because it is comprehensive. The flip side is that it is huge. Because there’s no code completion facilities that work with ExtJS (don’t get me started on the waste of effort that is the Eclipse plugin) it’s necessary to remember lots of stuff which I find impossible. As a result I’m consulting the API reference help (which is very good) all the time.

However there are some common patterns that I reuse so this post is to, over time, document these patterns. Most are to do with manipulating flat and tree grids.

Refreshing the data of a single node

In ExtJS code, grid rows are referred to as ‘node’s whether the grid is flat or a tree. The grid’s view exposes a method called ‘refreshNode’ which takes an integer value as an argument. The integer is the index of the corresponding record in the attached store. So to refresh a grid row its necessary to find out the index and fortunately there is a view method called ‘indexOf’ which accepts a model as it only argument. Update the row then is this line:

myGrid.getView().refreshNode(myGrid.getView().indexOf(arecord));

This line might be used in a grid’s ‘selectionchange’ event. The model records corresponding to the row(s) selected/being changed are passed as an array in the event’s ‘selections’ parameter. So ‘arecord’ in the line above might be ‘selection[0]’

record.data vs record.getData()

The sanctioned way to access the data associated with a model instance is to use the getData() method. However, updates to members of the returned object do not update the source because getData() appears to create a copy. Instead the proper way to update data is to call the ‘set’ method. However this causes the data to be marked as dirty which may or may not be desirable.

The alternative is to access the model’s ‘data’ property. This is the source data.

Processing all models of a tree

A tree store exposes the getRootNode() method to gain access to the mode records which support the tree view. Each node is a model instance augmented by a NodeInterface implementation. NodeInterface methods support finding nodes in the tree. Most find methods, such a ‘findChildBy’ support a parameter which indicates whether the search should be recursive.

The interface also provides the ‘eachChild’ method to iterate over the children of a node. However this method does not support an option to use recursion. The solution is to take advantage of the function parameter and use it as a lambda. Ordinarily this method may be used in this fashion:

myGrid.getStore().getRootNode().eachChild(function(node) {// do something with/to the node}, this);

However this will only touch each child of the root node. Here’s what to do if its necessary to touch all nodes:

var fn = function(node)
{
    // do something with/to the node then recurse
    node.eachChild(fn, this);
};
myGrid.getStore().getRootNode().eachChild(fn, this);

This is pretty much what you’d do in C# except the function would be a delegate.

Models are ExtJS objects too

A model definition only allows members to be simple types (int, string, boolean, etc). Sometimes it’s helpful to be able to include unstructured data or may be an object literal. The challenge is the how to present (or represent) such data in grid?

In one case a field holds keys which are the selections from what is conceptually a detail table. This field is an array of objects and each object has properties of ‘name’ and ‘value’. In this case I want the field to show a comma delimited list of the names. If this field were just an array, this would be easy because array.toString() returns this output.

The solution is to add a method to the model, for example ‘getNames()’ which returns an array of names. A function can’t be used directly in a grid so instead override the ‘renderer’ method of a regular column and call ‘this.getNames()’.

Changing the DOM row element of a grid

The grid’s view (mygrid.getView()) has a getNodeByRecord() method which takes a record instance as its only argument. The resulting node can be passed to the Ext.get() method so the DOM elements can be manipulated to, for example, dynamically add a CSS class or change/add/delete another attribute:

Ext.get(mygrid.getView().getNodeByRecord(record)).addCls("mycss")

This presumes a record instance has been obtained but this is true in, say, a selection change event. It’s also true when iterating over nodes using the code in previous sections.

Information and Links

Join the fray by commenting, tracking what others have to say, or linking to it from your blog.


Other Posts

Reader Comments

Sorry, comments are closed.