Understanding Flex 3 Migration Issues (Part I)

After several public and private betas, Flex 3 was released along with AIR 1.0 last Monday. Yipee! We’ve so far heard several customers who are looking for an official migration guide for getting their Flex 2 applications to work in Flex 3. I’m sorry to say that there isn’t an official migration guide. The reason is because from Flex 2 to 3, there were very few (if any) API changes. It was a MUCH bigger transition for applications going from Flex 1.5 to 2.0 when our product went through a huge API scrub and move to Actionscript 3.0.

Still, some of you may be finding that your application doesn’t quite behave the same or look the same in Flex 3.0. For these problems, your best two resources would be two backwards compatibility docs provided by Adobe’s doc team

http://learn.adobe.com/wiki/display/Flex/Backwards+Compatibility+Issues#BackwardsCompatibilityIssues-BackwardsCompatibilityCompilerOption

This document provides a list of changes in the Flex Framework that are supported by the a backwards compatibility flag in the compiler (-compatibility-version=2.0.1). For example, padding in Button never worked correctly before Flex 3. So, we fixed it. However, some people who may rely on the old measurement logic of the Button may not want to change their code to work with Flex 3’s padding changes. In your application, you can bring back the old behavior in Flex 2.0.1 by compiling their applications with the additional compiler argument -compatibility-version=2.0.1. However, beware, using the backwards compatibility flag is a “all or nothing” situation. If you compile your application with this flag, you will bring back all of the 2.0.1 behavior in the above document. You cannot pick and choose which compatibility changes to revert back.

There is also one document of backwards compatibility changes that are not supported by the -compatibility-version compiler argument. These changes come with Flex 3 and you need to live with it.

http://learn.adobe.com/wiki/display/Flex/Backwards+Compatibility+Issues#BackwardsCompatibilityIssues-ChangesNotSupportedByTheBackwardsCompatibilityFlag

For this week, I thought I would post about some changes in the framework that will likely cause some differences in Flex 2 applications.

Button Changes

Issue during migration: Button labels are now truncated. For example, this code produces a truncated label in Flex 3, but, not Flex 2.

<mx:Button label=”blue moon party” width=”105″ />

Cause of compatibility issue: In Flex 3, all Buttons have paddingLeft, paddingRight, paddingTop and paddingBottom of 10, by default. Padding styles didn’t work in Flex 2.0.1. The space to the left and right of the Button label in Flex 2.0.1 varied.

Fix: Adjust the paddingStyles. For example –

<mx:Button label=”blue moon party” width=”105″ paddingRight=”1″ paddingLeft=”1″/>

Issue during migration: The Event.CHANGE event no longer triggers on a Button or CheckBox unless there is user interaction. If the selected property changes programatically, the event doesn’t trigger.

Cause of compatibility issue: There needed to be a distinction of changing the selected property from user interaction vs programmatically.

Fix: If your code changed the selected property, it should know what to do when this happens.

DataGrid Changes:

Issue during migration: DataGrid code that relied on rowCount does not behave the same.

Cause of compatibility issue: rowCount and lockedRowCount no longer include the header. Also, the itemClick event’s rowIndex property returns 0 for the first row of data.

Fix: Adjust your code to look for different rowCount values. Most likely, you’ll need to subtract 1 from any rowCount value used in Flex 2.0.1.

Issue during migration: You get a runtime error or wrong behavior in a custom component that subclassed DataGrid. In this subclassed component, you used MyDataGrid.getChildAt(…) to access various children of the DataGrid, like the vertical scrollbar.

Cause of compatibility issue: The order of children in the DataGrid was changed. For example, in Flex 2, MyDataGrid.getChildAt(3) used to yield the vertical scrollbar. In Flex 3, it doesn’t. MyDataGrid.getChild(4) yields the scrollbar. In general, you shouldn’t expect the order of children to stay the same. We don’t guarantee this.

Fix: If possible, don’t use getChildAt to access internal components of the DataGrid. Otherwise, adjust which child you are accessing.

more ahead…

18 responses

  1. Hi Joan,

    I don’t want to sound like a whinging pom, but my migration attempt completely failed, as most of my calls to HTTPService stopped working. After investigation I found that functionality is broken only there, where I send XML objects to server. In the rest of the cases – nothing has changed.
    I have submitted a bug https://bugs.adobe.com/jira/browse/SDK-14811
    I created a very simple test case – HTTPService which sends XML and it ends up with empty request on server.
    If instead of XML I use unnamed Object – everything is fine. If you compile this test case with Flex 2 – everything is fine again. This is a clear case when valid Flex 2 code stops working under Flex 3.

    I will be very happy if Flex Team at least could confirm the bug or come out with workaround.

    Thank you!

    Regards,
    Dmitri Girski.

  2. Dmitri,

    Someone will definitely be looking into your bug since its already in the “New” status. You should get some comments in the bug within a few days. I personally don’t know that much about the HTTPServices changes. Filing the bug was your best bet for figuring out what is going on. Thanks. -Joan

  3. Hi Joan…. great work. This is exactly what the community needed

  4. Can you tag these posts as “Flex Migration” or something, so that i can link to it in one go? 🙂

    Raghu

  5. @Raghu: Done! I’ve tagged these entries and a couple others as ‘Flex Migration’. Sorry, these aren’t always the most organized 🙂

  6. I have noticed that a rowcount tag on my datagrid won’t limit the number of displayed items in said DataGrid. Is this because the the DataGrid is bound to my model, which is resetting the row count?

    Is there a way to limit the number of rows in this view, without editing the data in my model?

    Thanks

  7. @Rob: Setting rowCount should limit the number of visible rows in your DataGrid (regardless of your dataProvider). Can you post a snippet of your code. Just post the DataGrid code and a sample of your data. Thanks.

  8. i have migrated my application from Flex2 to Flex3 and everything works fine when i have in my web.xml as the following code..

    MainPage.mxml
    MainPage.mxml

    But in this way i am not able to access Advanced Data Grid and it says
    “Could not resolve to a component implementation.”
    But when i put it in web.xml as MainPage.html it gives an error as
    faultCode:Client.Error.MessageSend
    faultString:’Send failed’
    faultDetail:’Channel.Connect.Failed error
    NetConnection.Call.Failed: HTTP: Status 404:
    url: ‘http://localhost:8080/WebContent/messagebroker/amf”

    Could anyone please tell what the problem is???

    Thanks in advance

  9. there was a typo in line 4 …in the prev message…
    in web.xml
    i meant the welcome-file-list tag..if i give it as MainPage.mxml

  10. I’m not sure of about this problem. You might want to try asking on flexcoders. Also, search the bugbase for this error. What is the purpose of web.xml? Is this the dataProvider of your AdvancedDataGrid? Are you using LCDS?

  11. prashant shelke | Reply

    Hi,

    I have just migrated my project to flex 3.0, I have resolved few warnings for resourceBundle. But Some editable dataGrid cell onFocusOut causing this error:
    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at mx.controls::DataGrid/destroyItemEditor()
    at mx.controls::DataGrid/itemEditorItemEditEndHandler()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()
    at mx.controls::DataGrid/endEdit()
    at mx.controls::DataGrid/collectionChangeHandler()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.collections::ListCollectionView/dispatchEvent()
    at mx.collections::ListCollectionView/replaceItemsInView()
    at mx.collections::ListCollectionView/listChangeHandler()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.collections::ArrayList/setItemAt()
    at mx.collections::ListCollectionView/setItemAt()
    Which results in closing of browser 😦
    Can u please suggest any help ?
    Thanks.

  12. @prashant: Can you give more details about your DataGrid? Are you using a custom itemEditor? If you want, you can file a bug at http://bugs.adobe.com/flex. Post the bug # here and I can take a look. – Joan

  13. I will be very happy if Flex Team at least could confirm the bug or come out with workaround.
    Thank you! 🙂

  14. Thanks for the info on migration 2 to 3. You saved me lots of time scratching my head (being new to flex and having migration as my first job). I found that when dealing with DataGrid, after migration – whatever row item click event I selected the pop-up would show info for the row immediately above, and I could not select the first row.
    In the click event’s function I found the code read “selMetricName = searchedMetricsAC[event.rowIndex-1].Column4;” having many similar entries. I found that by deleting ‘-1’ thereby having the code read “selMetricName = searchedMetricsAC[event.rowIndex].Column4;” I made the application work. I’m not sure if this is what you refered to in your text above.

    Cheers.

  15. 1. I want to add one row above the datagrid header is that possible ?
    2. I want to put the item renderer for only one row ?

    expecting the reply .

    thank you friends.

  16. @lakshmikanth :
    1) You will want to use a custom headerRenderer. You can find an example here: http://blogs.adobe.com/aharui/item_renderers/ There will not be an extra row above the header, but, you can make it look like its an extra row.
    2) An itemRenderer has to apply to an entire column. However, if you control what the itemRenderer does according to its data, then, you should be able to get it change behavior only for one row. For example, if you want the row with data.quantity=0 to have a red background, then you would use the same itemRenderer in each column. In that itemRenderer, you would override the set data function. In the set data function, you would check the data for data.quantity==0. If that is true, you’d draw a red background. Hope that helps.

    Joan

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: