Extending Custom Flex 2 MXML Components

It occurs to me that there is likely to be quite a few people interested in component development in Flex 2 (Bit of a no brainer really). However I thought I’d do a set of posts focused on tips and tricks to make rapid development of Flex 2 MXML based components more productive (Actionscript 3 ones to follow). This isn’t a ‘cook book’ solution but it does fall in that arena. So to kick it off I thought I’d continue on from my last post and show how to override the default values of a component from a component that inherits from it and from within a composited component.

To do this I will concentrate on my 2 example ComboBox components FGComboBox and FGExtendedComboBox. These aren’t really that useful in a production environment but help to illustrate code examples. To start with let’s recap on the two components.

First up we have FGComboBox:

<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:dataProvider>
		<mx:String>Miss</mx:String>
		<mx:String>Mrs</mx:String>
		<mx:String>Mr</mx:String>
		<mx:String>Dr</mx:String>
	</mx:dataProvider>
</mx:ComboBox>

Next up we have FGExtendedComboBox:

< ?xml version="1.0" encoding="utf-8"?>
<fgcombobox xmlns="com.flashgen.components.flex.controls.*" xmlns:mx="http://www.adobe.com/2006/mxml">
</fgcombobox>

As you can see FGExtendedComboBox inherits from FGComboBox but does nothing more. That’s fine but what if we want to override the dataProvider? Well we can tackle this in two ways. We can either implement a dataProvider in the component body or we can place a piece of script in the code to set the dataProvider. There is a slight deviation though, this is due to the fact that once you have extended a component it takes all of its information from the parent class and namespace. So you will get an error if you try and use <mx:dataProvider></dataProvider> inside FGExtendedComboBox.

To get around this you have a couple of options from within the component. The first is to just use Actionscript to set the dataProvider. As you can see from the code below we call setData() once the component has initialized. This in turn sets the dataProvider inside our component. Now if you chose to set the value of a property within the component bare in mind that it will likely resolve before the rest of the application has finished its own initialization / creation.

< ?xml version="1.0" encoding="utf-8"?>
<fgcombobox xmlns="com.flashgen.components.flex.controls.*" xmlns:mx="http://www.adobe.com/2006/mxml" initialize="{setData()}">
	<mx :Script>
		< ![CDATA[
			private function setData():void
			{
				this.dataProvider = ["Three","Two","One"]  // 'this' is only present to explicitly indicate we are accessing the components dataProvider
			}
		]]>
	</mx>
</fgcombobox>

Secondly there is setting the dataProvider within the component via MXML. However as we cannot access <mx:dataProvider> how do we do this? Well if you think about it is a logical way it will become eveident. Considering we use ‘this’ to access the component dataProvider method with Actionscript it makes sense that we do the same with the MXML. In this case though we can be implicit with the notion of ‘this’ and just provide a <dataProvider></dataProvider> tag block. Once we have that in place we can go back to using <mx:…> tags within it as you can see below:

< ?xml version="1.0" encoding="utf-8"?>
<fgcombobox xmlns="com.flashgen.components.flex.controls.*" xmlns:mx="http://www.adobe.com/2006/mxml">
	<dataprovider>
		<mx :String>Three</mx>
		<mx :String>Two</mx>
		<mx :String>One</mx>
	</dataprovider>
</fgcombobox>

Obviously it would add clarity if there was a namespace associated with properties that you were going to access internally from the parent. You can do this but it requires you to add in those additional namespaces. It doesn’t appear to add anything beyond clarity in the code so I would just choose whichever one suits your requirements. Below are a few other variants that you can employ including the additional namespace, accessing the super.dataProvider (don’t use this one unless you have a specific reason for altering the parent property).

< ?xml version="1.0" encoding="utf-8"?>
<fgcombobox xmlns="com.flashgen.components.flex.controls.*" xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:fgx="com.flashgen.components.flex.controls.*">
 
// Here we have added in an additional namespace so we can clarify our dataProvider
 
	<fgx :dataProvider>
		<mx :String>Three</mx>
		<mx :String>Two</mx>
		<mx :String>One</mx>
	</fgx>
</fgcombobox>

This one utilizes a call to the parent property / method via super(). Not really a solution you are likely to use when extending the MX components but you may wish to do this in a bespoke creation of your own.

< ?xml version="1.0" encoding="utf-8"?>
<fgcombobox xmlns="com.flashgen.components.flex.controls.*" xmlns:mx="http://www.adobe.com/2006/mxml" initialize="{setData()}">
	<mx :Script>
		< ![CDATA[
			private function setData():void
			{
				super.dataProvider = ["Three","Two","One"]  // 'this' is only present to explicitly indicate which dataProvider we mean
			}
		]]>
	</mx>
</fgcombobox>

So that’s about it. From my experience it is easier to start with MXML component development and move onto Actionscript 3.0 component development. Not because AS3.0 is harder, but for the time being pretty much all of your AS3.0 development is going to revolve around Flex (until Flash 9 is released). So to get used to the MXML syntax it makes sense to start from that direction. I’m working on some AS3.0 examples, articles and musings so stick with it – Knowing Flex will pay dividends even if you are a ‘die-hard’ Flasher.

Flash on the BeachCatch my talk on Flex 2 and AS3 component development at Flash on the Beach
December 4th-6th 2006 Brighton, UK

Mike Jones