I recently upgraded to Sencha Touch 2.1.0 and noticed that the dataMap setters on my ListItems weren't being created for the list item and, because of this, my components weren't being populated with data. After some investigation, I found that when a list item is created and begins searching through the dataMap for setters, it looks for that setter on both the component AND the data.

Here's a snippet of code to explain a bit better:

Code:
Ext.define('MyApp.view.search.SearchHitlistItem', {
    extend: 'Ext.dataview.component.DataItem',
    xtype: 'search_hitlist_item',
    itemId: 'hitlist_item',


    config: {
        topContainer: true,
        bottomContainer: true,
		dataMap: {
	        getTopContainer: {
		        doBuild: ''
	        },
	        getBottomContainer: {
		        doBuild: ''
	        }
        }
    },
    
    applyTopContainer: function(config) {
        return Ext.factory(config, MyApp.view.search.SearchHitlistItemTop, this.getTopContainer());
    },
    
    updateTopContainer: function(newContainer, oldContainer) {
        if (oldContainer) {this.remove(oldContainer);}
        if (newContainer) {this.add(newContainer);}
    },


    applyBottomContainer: function(config) {
        return Ext.factory(config, MyApp.view.search.SearchHitlistItemBottom, this.getBottomContainer());
    },


    updateBottomContainer: function(newContainer, oldContainer) {
        if (oldContainer) {this.remove(oldContainer);}
        if (newContainer) {this.add(newContainer);}
    }
});
Code:
Ext.define('MyApp.view.search.SearchHitlistItemTop', {
    extend: 'Ext.Container',
    config: {
        //....
    },
   
    doBuild: function() {
        this.buildCoverArt();
        this.buildFields();
    },
    buildFields: function() {
        //Bunch of stuff happens here
    },
    
    buildCoverArt: function() {
        //Bunch of stuff happens here
    }
});
doBuild is a method on the SearchHistlistItemTop and Bottom views. From looking at the DataItem code, it does the following when constructing the ListItem:

Code:
doMapData: function(dataMap, data, item) {
        var componentName, component, setterMap, setterName;


        for (componentName in dataMap) {
            setterMap = dataMap[componentName];
            component = this[componentName]();
            if (component) {
                for (setterName in setterMap) {
                    if (data && component[setterName] && data[setterMap[setterName]]) {
                        component[setterName](data[setterMap[setterName]]);
                    }
                }
            }
        }


        if (item) {
            // Bypassing setter because sometimes we pass the same object (different properties)
            item.updateData(data);
        }
    },
The bolded statement above ends up preventing the setter from being generated. Is this intentional? It appears to try to find doBuild on the corresponding Model for this item. I've made changes in my own code to not look for 'doBuild' on the model and, after the if-statement passes, passing the full model to the component so it can decide what data it needs from the model.

This works great for my more complicated, self-constructing views, but I could see how this wouldn't work with standard components that are expecting a specific piece of data (like the Label component calling setText and expecting a string). But for custom dataMap methods, this seems to the best way to make complex ListItems (without having to resort to using a template).

Also, am I abusing the ListItem? Is this an unintended usage of the DataItem and will using it this way have consequences in the future? (Beyond performance implications of having multiple complex views)