    /** * A ListItem is a container for {@link Ext.dataview.List} with  * useSimpleItems: false.  *  * ListItem configures and updates the {@link Ext.data.Model records} for   * the sub-component items in a list.  *    * Overwrite the `updateRecord()` method to set a sub-component's value.  * the framework calls `updateRecord()` whenever the data in the list updates. * * The `updatedata` event fires after `updateRecord()` runs. * * *Note*: Use of ListItem increases overhead since it generates more markup than * using the List class with useSimpleItems: true. This overhead is more * noticeable in Internet Explorer. If at all possible, use * {@link Ext.dataview.SimpleListItem} instead via the List's * {@link Ext.dataview.List#useSimpleItems useSimpleItems} config. * * The following example shows how to configure and update sub-component items * in a list: * *     Ext.define('Twitter.view.TweetListItem', { *         extend: 'Ext.dataview.ListItem', *         xtype : 'tweetlistitem', *         requires: [ *             'Ext.Img' *         ], *         config: { *             userName: { *                 cls: 'username' *             }, *             text: { *                 cls: 'text' *             }, *             avatar: { *                 docked: 'left', *                 xtype : 'image', *                 cls   : 'avatar', *                 width: '48px', *                 height: '48px' *             }, *             layout: { *                 type: 'vbox' *             } *         }, *      *         applyUserName: function(config) { *             return Ext.factory(config, Ext.Component, this.getUserName()); *         }, *      *         updateUserName: function(newUserName) { *             if (newUserName) { *                 this.insert(0, newUserName); *             } *         }, *      *         applyText: function(config) { *             return Ext.factory(config, Twitter.view.TweetListItemText, this.getText()); *         }, *      *         updateText: function(newText) { *             if (newText) { *                 this.add(newText); *             } *         }, *      *         applyAvatar: function(config) { *             return Ext.factory(config, Ext.Img, this.getAvatar()); *         }, *      *         updateAvatar: function(newAvatar) { *             if (newAvatar) { *                 this.add(newAvatar); *             } *         }, *      *         updateRecord: function(record) {      *             if (!record) { *                 return; *             } * *             this.getUserName().setHtml(record.get('username')); *             this.getText().setHtml(record.get('text')); *             this.getAvatar().setSrc(record.get('avatar_url')); *             this.callParent(arguments); * *         } *     }); * */Ext.define('Ext.dataview.ListItem', {    extend: 'Ext.dataview.component.DataItem',    alternateClassName: 'Ext.dataview.component.ListItem',    xtype: 'listitem',     requires: [        'Ext.dataview.ListItemBody',        'Ext.dataview.ListItemDisclosure'    ],     config: {        dataMap: null,         body: {            xtype: 'listitembody'        },         disclosure: {            xtype: 'listitemdisclosure',            hidden: true,            docked: 'right'        },         header: {            xtype: 'itemheader'        },         tpl: null,        items: null    },     classCls: Ext.baseCSSPrefix + 'listitem',    classClsRoot: true,     initialize: function() {        var me = this,            body, disclosure;         me.callParent();         this.syncUi();         body = me.getBody();        disclosure = me.getDisclosure();         if (body) {            me.add(body);        }         if (disclosure) {            me.add(disclosure);        }    },     applyBody: function(body) {        if (body && !body.isComponent) {            body = Ext.factory(body, Ext.Component, this.getBody());        }         return body;    },     updateBody: function(body, oldBody) {        if (body && !this.isConfiguring) {            this.add(body);        }         if (oldBody) {            oldBody.destroy();        }    },     applyHeader: function(header) {        if (header && !header.isComponent) {            header = Ext.factory(header, Ext.Component, this.getHeader());        }         return header;    },     updateHeader: function(header, oldHeader) {        if (oldHeader) {            oldHeader.destroy();        }    },     applyDisclosure: function(disclosure) {        if (disclosure && !disclosure.isComponent) {            disclosure = Ext.factory(disclosure, Ext.Component, this.getDisclosure());        }         return disclosure;    },     updateDisclosure: function(disclosure, oldDisclosure) {        if (disclosure && !this.isConfiguring) {            this.add(disclosure);        }         if (oldDisclosure) {            oldDisclosure.destroy();        }    },     updateTpl: function(tpl) {        this.getBody().setTpl(tpl);    },     updateUi: function(ui, oldUi) {        this.callParent([ui, oldUi]);         if (!this.isConfiguring) {            this.syncUi();        }    },     updateRecord: function(record) {        var me = this,            dataview = me.dataview || this.getDataview(),            data = record && dataview.prepareData(record.getData(true), dataview.getStore().indexOf(record), record),            dataMap = me.getDataMap(),            body = this.getBody(),            disclosure = this.getDisclosure();         me._record = record;         if (dataMap) {            me.doMapData(dataMap, data, body);        } else if (body) {            body.updateData(data || null);        }         if (disclosure && record && dataview.getOnItemDisclosure()) {            var disclosureProperty = dataview.getDisclosureProperty();            disclosure[(data.hasOwnProperty(disclosureProperty) && data[disclosureProperty] === false) ? 'hide' : 'show']();        }         /**         * @event updatedata         * Fires whenever the data of the DataItem is updated.         * @param {Ext.dataview.component.DataItem} this The DataItem instance.         * @param {Object} newData The new data.         */        me.fireEvent('updatedata', me, data);    },     doDestroy: function() {        Ext.destroy(this.getHeader());        this.callParent();    },     privates: {        syncUi: function() {            var me = this,                ui = me.getUi(),                body = me.getBody(),                disclosure = me.getDisclosure();             if (body) {                body.setUi(ui);            }             if (disclosure) {                disclosure.setUi(ui);            }        }    }});