Getting Live Updates when Changing Stores in Ext JS

My current project is a very interactive web application that makes heavy use of client-side JavaScript. The application is being developed with Sencha’s Ext JS JavaScript framework (currently using version 4.0). I am still pretty new to Ext JS, so I find my self occasionally fighting with the framework to achieve my end goal. I want to share one tip I learned the hard way.

Source & Destination Data Stores Not Live Updating

I was working on a page that displayed two lists (or grids in Ext JS terms). One was the source and the other the destination. Items could be dragged from the source list and dropped into the destination list. The two lists were backed by separate Ext.data.Store instances. I initially had the following code in the drop handler:

  destinationStore.add(droppedModel);
  sourceStore.remove(droppedModel);

Obviously this code moves the model from one store to the other. And thanks to the magic of Ext JS, both the source and destination lists on the page are automatically updated to reflect the change.

But there was a problem. While the item would show up in the destination list, the attributes displayed for the item would not live update when they were changed by other actions on the page. Saving and refreshing the page fixed the problem, so I knew I had correctly wired up the other controls. There had to be another issue.

From One Store To the Next

After some investigation, I was able to trace the problem back to the way that Ext JS routes events from the model to the view. Each model has a store attribute, and when something changes on the model, it tells its store. The store then fires an event that the displayed list picks up, causing it to refresh the display.

When you add a model to a store, the model’s store attribute is updated to point to that store. When you remove a model from a store, the model’s store attribute is cleared. The problem is that no check is made to see if the model’s store attribute actually points to that store — it gets cleared regardless.

The fix was to just reverse the order of operations, making sure the model gets removed from the old store before it’s added to the new store.

  sourceStore.remove(droppedModel);
  destinationStore.add(droppedModel);

In hindsight, it does make more sense to remove something from one place before adding it to something else.

In addition to fixing the bug, I now know that an Ext JS model only knows about the last store it was added to, and that is the store that gets notified when it’s changed — very useful information when you’re moving models from store to store on a page.