3
votes

I havent found quite what I want elsewhere or at least am not accomplished enough to adapt

I'm trying to create a project that shows radio stations with logo, listen button etc

The datasource is an xml file with child tags like 'name','image' and 'listen' for each parent, 'station'. I access this data via the main application with creationComplete="radioService.send()" I can then use it on the main app via dataProvider="{radioService.lastResult.stations.station}

However, I want to use the results to populate variables in the custom component in both the components themselves

hard coded examples

mx:Image source="Images/BBC5.gif" id="bbc5Logo" "/>

mx:LinkButton id="bbc5Listen" click="bbc5Listen_clickHandler(event)" />

and in the clickhandler

protected function bbc5Listen_clickHandler(event:MouseEvent):void {

var url:String = "http://www.bbc.co.uk/iplayer/console/bbc_radio_five_live"; var request:URLRequest = new URLRequest(url);

} Any help, much appreciated

5

5 Answers

0
votes

I done something similar before though I am not sure of what look and feel you wish your app to have but it would be possible to create a Datagrid and bind the datasource to that grid. Then you can add fields to the datasource like ( img field and use the link in the XML by setting the xpath towards that field) , it would also be possible to create a button and place that in the row of the datagrid for listen.

Obviously this is a slightly different implementation but the same principle applys if you have created a custom component then make sure it makes use of DataSource and DataSource fields which will aquire the data from the right part of the XML. Then it would be possible to map that DataSource field to a String for example.

Hope this helps

0
votes

You can actually use Custom Events, where you can pass values from your main app to your custom component.

http://www.anujgakhar.com/2009/03/04/flex-passing-data-with-custom-events/

0
votes

Another approach could be to create Value Objects from your XML and bind your components to these objects, this way you would decouple your components from the XML , which can be handy if at some point in the future, you don't want to use XML, but JSON for instance.

Each Value Object would have the properties defined in your question , i.e , imageSource , id , url etc... and each component would be bound to one Value Object

Edit Have a look at this video training, it covers data retrieval from an XML , ArrayCollections of ValueObjets etc...
http://www.adobe.com/devnet/flex/videotraining.html

0
votes

there are two ways to accomplish this:

  • you should wrap your data structure from xml source to a [Bindable] actionscript object (not mandatory, but you can handle it easier), and bind the array of these data instances (let's say RadioChannel.class) as the dataProvider of your grid. Inside your itemRenderer implementation you can access the current row's RadioChannel instance via the data getter/setter:

RadioChannel.as:

[Bindable]
public class RadioChannel {

    private var _name: String;
    private var _imageUrl: String;
    private var _listenUrl: String; 

    public function RadioChannel()
    {
    }

    public function get name():String {return _name;}
    public function set name(value:String):void {_name = value;}

    public function get imageUrl():String {return _imageUrl;}
    public function set imageUrl(value:String):void {_imageUrl = value;}

    public function get listenUrl():String {return _listenUrl;}
    public function set listenUrl(value:String):void {_listenUrl = value;}

    public function toString():String
    {
        return 'RadioChannel ' + name + ' - image: ' + imageUrl + 
            ' | listen at ' + listenUrl;

    }
}

RadioList.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:DataGrid xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" dataProvider="{radioChannels}">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;

            private var _radioChannels:ArrayCollection = new ArrayCollection();
            [Bindable]
            private function get radioChannels():ArrayCollection {return _radioChannels;}
            private function set radioChannels(value:ArrayCollection):void {_radioChannels = value;}

        ]]>
    </fx:Script>
    <mx:columns>
        <mx:DataGridColumn>
            <mx:itemRenderer>
                <fx:Component>
                    <mx:Image source="{data.imageUrl}">
                        <fx:Script>
                            <![CDATA[

                                public override function set data(value:Object):void
                                {
                                    super.data = value;
                                    trace('current instance: ' + RadioChannel(data).toString());
                                }

                            ]]>
                        </fx:Script>
                    </mx:Image>
                </fx:Component>
            </mx:itemRenderer>
        </mx:DataGridColumn>
        <mx:DataGridColumn dataField="name" />
        <mx:DataGridColumn>
            <mx:itemRenderer>
                <fx:Component>
                    <mx:HBox>
                        <fx:Script>
                            <![CDATA[
                                protected function onLinkClicked(event:MouseEvent):void
                                {
                                    var currentChannel:RadioChannel = RadioChannel(data);
                                    if (data)
                                    {
                                        var request:URLRequest = new URLRequest(currentChannel.listenUrl);
                                        [...]
                                    }
                                }

                            ]]>
                        </fx:Script>
                        <mx:Button click="onLinkClicked(event)" label="Listen" />
                    </mx:HBox>
                </fx:Component>
            </mx:itemRenderer>
        </mx:DataGridColumn>
    </mx:columns>
</mx:DataGrid>
  • The other way is to build up custom events that deal with an extra parameter: the url of the channel. These custom events should cascade back to the list component, where they should be handled.

Since for the second solution you would still need the first's binding as well, i'd choose the first one, and handle the click event locally.

hope this helped.

0
votes

I think this may be useful, to pass the value from mainApp to custom component you can follow this method.Since you have the value in mainApp,in the custom component you can access the value by using parentDocument object.parentDocument.rootAppVar