9 Replies Latest reply on Nov 24, 2006 3:22 AM by parallaxed

    itemRenderer in TileList

      I have a TileList displaying images loaded from a ByteArray. In MXML
      code I have something like

      <mx:TileList id="myTileList" dataProvider="{CairngormModel.byteArray}"
      itemRenderer="MyItemRenderer" />

      MyItemRenderer is just a class that extends mx.controls.Image. The
      data setter is overriden, loading the passed ByteArray into a Loader.

      The MXML code above works and renders fine, however I'm trying to do
      the equivalent in actionscript, which should go something like this:

      > public class MyTileList
      > {
      > private myTileList:TileList = new TileList();
      > public function MyTileList()
      > {
      > myTileList.itemRenderer = new ClassFactory(MyItemRenderer);
      > BindingUtils.bindProperty(myTileList,"dataProvider",CairngormModel,"byteArray");
      > }
      > override protected function createChildren():void
      > {
      > addChild(myTileList);
      > }
      > }

      Yet this doesn't render anything. The debugger indicates the
      dataProvider field never changes (is always null). Why isn't the
      binding executing?

      The alternative approaches I've tried include binding a setter to the
      CairngormMode.byteArray, using bindSetter(). This function triggers
      when the value changes, so I just set myTileList.dataProvider manually
      within the setter. This is followed with a call to
      myTileList.invalidateProperties() - still nothing is rendered, even
      though the debugger reports the dataProvider as the ByteArray.

      Am I missing something simple? Why does the MXML work and not the ActionScript?

      Any clues would be much appreciated.
        • 1. Re: itemRenderer in TileList
          ntsiii Level 3
          Start by extending TileList:
          public class MyTileList extends TileList

          Your custom class as is does not have a dataProvider attribute.
          • 2. itemRenderer in TileList
            parallaxed Level 1
            In the above example, var myTileList is of type TileList, so it does have a dataProvider attribute. The custom class is just a container for the TileList. In the implementation I'm using, it extends VBox.
            • 3. Re: itemRenderer in TileList
              ntsiii Level 3
              I don't think so but if you are sure you know what you are doing, ok.

              • 4. Re: itemRenderer in TileList
                jpwrunyan Level 1
                I assume you just forgot to write "extends VBox".
                One thing that immediately comes to mind is that you are instantiating a new TileList() in the variable declaration. In AS 2.0 this was very problematic. I always leave my variable declarations null and then instantiate them in their getter/setter, (sometimes) the constructor, or (preferably) the createChildren() method. See if that makes a difference. I haven't delved into the issue in AS 3.0 but in 2.0 non-primitives instantiated in the class declaration were stored on the prototype level and then shared by all instances of the class almost as though they were static references. Whether that is still true or not, for sanity's sake you should conglomerate all your instantiation, initialization, and display code for child components in createChildren(). Also always call super()!

                I rarely use the constructor to do anything but work with parameters passed to it (which with UIComponents is almost always nil--use getter/setters instead in these cases).

                If by doing this you don't solve your problem, you will still be a step closer to effectively debugging it. If you are using FlexBuilder you can also turn on an option to save the AS script derived from your MXML components and then see what is going on there when the MXML works but the AS does not. Even if you're not using FB, there is probably an option in the SDK for this as well.
                • 5. itemRenderer in TileList
                  parallaxed Level 1
                  The example above was purely theoretical. It's just the difference between the AS3 / MXML that I'm not too clear on. Does instantiating a component in MXML provide otherwise non-default parameters that have to be explicitly specified by AS3 during createChrildren() (or some other point in the drawing phase?)


                  Originally posted by: jpwrunyan
                  If you are using FlexBuilder you can also turn on an option to save the AS script derived from your MXML components and then see what is going on there when the MXML works but the AS does not.

                  I am using flex builder, but haven't come across this option yet. Could you drop me a hint as where to find it?

                  • 6. Re: itemRenderer in TileList
                    jpwrunyan Level 1
                    I guess the easy answer to your question would be "yes". But that is only because in the comparison of the two scripts you provided, mxml and AS, the mxml does not execute the way the theoretical AS does.

                    Also, I would not use BindingsUtil for what you are doing. Rather make a "dataProvider" property for your parent VBox (getter/setter) but a [Bindable] metadata tag over it, and in the function pass the argument of the setter method to the child Tile's dataProvider and in the getter method return the value of the Tile's dataProvider. This is easier in my opinion. This does assume your CairnGormModel is outside the overall custom component. If you still can't get things working, you will probably need to post the code. By the way, is this being done in an Actionscript project or a Flex project?

                    As for generating AS code looks like I was wrong, there is a feature for publishing source but it doesn't convert mxml to AS. It seems like there still ought to be a way to get the source from the mxml since the SDK (to my knowledge) has to convert mxml to AS before compiling the swf. If I do find something, I will let you know. I could have sworn there was a way to do it...
                    • 7. Re: itemRenderer in TileList
                      parallaxed Level 1
                      It's a flex project. Since the origial post things have progressed a little, but sometimes it feels like I'm battling for no reason over something that should be fairly simple...

                      Updates to follow
                      • 8. Re: itemRenderer in TileList
                        jpwrunyan Level 1
                        I knew I saw it somewhere:
                        Building and Deploying Flex 2 Applications > Building Flex Applications > Using the Flex Compilers > Using the application compiler > About the application compiler options

                        There is an option on the mxmlc called "keep-generated-actionscript"

                        Determines whether to keep the generated ActionScript class files.

                        The generated class files include stubs and classes that are generated by the compiler and used to build the SWF file.

                        The default location of the files is the /generated subdirectory, which is directly below the target MXML file. If the /generated directory does not exist, the compiler creates one.

                        The default names of the primary generated class files are filename-generated.as and filename-interface.as.

                        The default value is false.

                        This is an advanced option.

                        In FB right click on project, select properties, Flex Compiler, and in the Additional compiler arguments box, add the above parameter and set it to true. That should give you the as files for your mxml components, etc.
                        • 9. Re: itemRenderer in TileList
                          parallaxed Level 1
                          Awesome stuff, thanks =)

                          I can see better into the problem now, although I'm still confused as to why that particular binding won't execute properly. I can do what you suggested with moving the data provider up a level, but I don't see how that helps other than to add a "middle-man" to the view...

                          So far I've attempted setting the dataProvider manually when the images in the tile list have loaded, but I just end up causing a muddle of Exceptions that I'm trying to decipher at the moment.