How to dynamically generate Sencha Touch radio buttons (Ext.field.Radio)

The following controller code shows how I dynamically render radio buttons in a Sencha Touch controller. Just scroll down and look for the recordedStreamsStore.each block of code:

Ext.define('RadioMobile.controller.RecordedStreamsController', {
    extend: 'Ext.app.Controller',

    requires: [
        'VP.util.Util',
        'RadioMobile.view.RecordingsPanel',
        'Ext.form.FieldSet',
        'Ext.field.Radio'
    ],

    config: {
        stores: [
            'RecordedStreams'
        ],
        views: [
            'RecordingsPanel'
        ],
        // "In the refs configuration, you can set up references to view instances. 
        //     This allows you to retrieve and manipulate components on the page inside of your controller’s actions."
        // "refs create a reference to a component ... basically using Ext.ComponentQuery#down."
        // "put a reference to a view instance (component) inside of a controller."
        refs: {
            // localVarName : itemId
            recordingsPanel : 'recordingsPanel'
        },
        // this is different in touch; i use an `init` method in ExtJS
        control: {
            recordingsPanel: {
                // eventWeGetFromTheViewComponent : 'localFunctionName'
                'initialize': 'onRecordedStreamsPanelBeforeRender'
            }
        },
    },

    onRecordedStreamsPanelBeforeRender: function(panel, options) {
        // console.log('ENTERED RecordedStreamsController::onRecordedStreamsPanelBeforeRender');
        var me = this;
        var recordedStreamsStore = Ext.getStore("RecordedStreams");
        recordedStreamsStore.load({
            callback: function(records, operation, success) {
                if (success === true) {
                    var fieldset = new Ext.form.FieldSet({});
                    recordedStreamsStore.each(function(record) {
                        var filename = record.data.filename;
                        // console.log('   stream: ' + filename);
                        var radioField = Ext.create('Ext.field.Radio', {
                            name: 'recorded_stream',
                            value: filename,
                            label: filename,
                            labelWrap: true,
                            labelWidth: '80%',
                            listeners: {
                                'check': function(radio, e, eOpts) {
                                    me.radioHandler(radio.getValue());
                                }
                            }
                        });
                        fieldset.add(radioField);
                    });
                    panel.add(fieldset);
                } else {
                    console.log('error: had a problem reading the recordedStreamsStore');
                }
            }
        });
    },

    // `radioValue` is like `104.3` (or in this case a filename)
    radioHandler: function(radioValue) {
        // console.log('YOU CLICKED: ' + radioValue);
        var encodedFilename = Ext.urlEncode({ recordingFilename: radioValue });
        Ext.Ajax.request({
            url: '/server/playRecording?' + encodedFilename,
            method: 'GET',
            success: function(conn, response, options, eOpts) {
                var result = VP.util.Util.decodeJSON(conn.responseText);
                if (result.success) {
                    // ignore
                } else {
                    VP.util.Util.showErrorMsg(result.msg);
                }
            },
            failure: function(conn, response, options, eOpts) {
                // TODO get the 'msg' from the json and display it
                VP.util.Util.showErrorMsg(conn.responseText);
            }
        });
    }

});

The Sencha Touch Panel (view)

That controller works with this simple Panel/view:

Ext.define('RadioMobile.view.RecordingsPanel', {
    extend: 'Ext.Panel',
    alias: 'widget.recordingsPanel',

    config: {
        xtype: 'recordingsPanel',
        itemId: 'recordingsPanel',
        title: 'Recordings',
        iconCls: 'time',

        scrollable: 'vertical',

        items: [
            {
                docked: 'top',
                xtype: 'titlebar',
                title: 'Recordings'
            }
        ],

    },

});

The Sencha Touch Store and Model

For the sake of completeness, here is the corresponding Sencha Touch Store:

Ext.define('RadioMobile.store.RecordedStreams', {
    extend: 'Ext.data.Store',

    requires: 'RadioMobile.model.RecordedStream',

    config: {
        model: 'RadioMobile.model.RecordedStream',
        proxy: {
            type: 'ajax',
            url: '/server/getRecordings',
            method: 'GET',
            reader: {
                type: 'json'
            },
            noCache: true
        }
    }

});

and the Model:

Ext.define('RadioMobile.model.RecordedStream', {
    extend: 'Ext.data.Model',

	config: {
	    fields: [
	        {name: 'filename'}
	    ]
	}

});

The code also shows some documentation on the Sencha refs element, which may be as useful as the code.