15 Replies Latest reply on May 18, 2008 1:59 AM by dam85

    Problem about  a new component

    dam85
      Hello everybody,
      I have a User.mxml file with a new component, this is the cose:

      <?xml version="1.0" encoding="utf-8"?>

      <mx:Canvas xmlns:mx=" http://www.adobe.com/2006/mxml" width="200" height="100">
      <mx:HBox horizontalGap="0">
      <mx:Image source="@Embed(source='../images/x.gif')" click="deleteUser();" />
      <mx:Button label="Name" click="showUser();" />
      </mx:HBox>
      </mx:Canvas>

      i have to call this compotent inside a <mx:Repeater> from another mxml file, below an example:

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns:my="components.*" layout="absolute">

      <mx:Repeater id="loop" dataProvider="{MyArray}">
      <my:User />
      </mx:Repeater>

      </mx:Application>

      i put also another namespace xmlns:my="components.*" (i have /components/User.mxml)

      ok...now.... the component has two objects: an Image and a Button, those objects has two listener(click() event)
      How can i get those events calls if i put my new component inside a repeater ?

      i have to know which my object(inside the repeater) has an event, and then i have to know which event has called(or Image event, or Button event)


      Thanks a lot!!


        • 1. Re: Problem about  a new component
          laurent_pinson
          In this example : http://livedocs.adobe.com/flex/3/langref/mx/core/Repeater.html#includeExamplesSummary

          You can see "event.currentTarget.getRepeaterItem()", did you try to identify your items with that?

          You can use this too :
          if(event.currentTarget is Image){
          ....
          }else if (event.curentTarget is Button){
          ...
          }else{
          ...
          }

          Laurent
          • 2. Problem about  a new component
            dam85 Level 1
            quote:

            Originally posted by: laurent pinson
            In this example : http://livedocs.adobe.com/flex/3/langref/mx/core/Repeater.html#includeExamplesSummary

            You can see "event.currentTarget.getRepeaterItem()", did you try to identify your items with that?

            You can use this too :
            if(event.currentTarget is Image){
            ....
            }else if (event.curentTarget is Button){
            ...
            }else{
            ...
            }

            Laurent


            good code!

            but in the repeater i have <my:User /> <--- my component
            i can't set click="" because (in this new component there are two objects)
            how could i do?

            thank you so much!!

            • 3. Re: Problem about  a new component
              dam85 Level 1
              ops, i get wrong....i think IS possible to set click=""

              i try....
              • 4. Re: Problem about  a new component
                dam85 Level 1
                ok, now i'm trying the code....

                another question....but is it possible to set the label and the source of the image inside the repeater?

                thanks
                • 5. Re: Problem about  a new component
                  Gregory Lafrance Level 6
                  I don't know exactly what behavior you are trying to achieve, need more details, but this might help a little:
                  • 6. Re: Problem about  a new component
                    dam85 Level 1
                    thanks!!

                    i try your code
                    • 7. Re: Problem about  a new component
                      dam85 Level 1
                      PERFECT!!!! It works perfectly!

                      The last questions:

                      1- Can i modify the label="" of the button inside my new component? (inside the repeater)

                      2- in the User.mxml i see parentApplication.showUser() what does mean? if i put another repeater inside Test.mxml how can i know which repeater has generated the events?

                      3. now i view the output: showUser() function called!!! deleteUser() function called!!! but how can i know which <my:User /> has generated the events?

                      4. i tried event.currentTarget but it return alwayes HBox, because it's the box of the objects inside my <my:User />
                      how can i do?


                      thanks a lot!!!
                      • 9. Re: Problem about  a new component
                        Gregory Lafrance Level 6
                        This is probably not the preferred way to do it:
                        ------------- User.mxml -------------------
                        <?xml version="1.0" encoding="utf-8"?>
                        <mx:Canvas xmlns:mx=" http://www.adobe.com/2006/mxml">
                        <mx:Script>
                        <![CDATA[
                        public function setButtonLabel(str:String):void{
                        btn.label = str;
                        }
                        ]]>
                        </mx:Script>
                        <mx:HBox horizontalGap="0">
                        <mx:Image id="img" source="@Embed(source='../images/x.gif')"
                        click="parentApplication.deleteUser();" />
                        <mx:Button id="btn" label="Name" click="parentApplication.showUser();" />
                        </mx:HBox>
                        </mx:Canvas>
                        -------------- Test.mxml -----------------
                        <?xml version="1.0" encoding="utf-8"?>
                        <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml"
                        xmlns:my="components.*" width="100%" height="100%">
                        <mx:Script>
                        <![CDATA[
                        [Bindable]
                        private var MyArray:Array = ["Button1", "Button2", "Button3", "Button4", "Button5"];
                        public function showUser():void{
                        txtArea.text += "showUser() function called!!!\n";
                        }
                        public function deleteUser():void{
                        txtArea.text += "deleteUser() function called!!!\n";
                        }
                        public function init():void{
                        for (var i:int = 0; i < user.length; i++){
                        user .setButtonLabel(MyArray);
                        }
                        }
                        ]]>
                        </mx:Script>
                        <mx:Tile creationComplete="init()">
                        <mx:VBox>
                        <mx:TextArea id="txtArea" width="200" height="300"
                        fontSize="12" text="Output:&#13;"/>
                        </mx:VBox>
                        <mx:Repeater id="loop" dataProvider="{MyArray}">
                        <my:User id="user"/>
                        </mx:Repeater>
                        </mx:Tile>
                        </mx:Application>
                        • 10. Re: Problem about  a new component
                          Gregory Lafrance Level 6
                          In parentApplication.showUser(), parentApplication allows you to access variables and methods of the app that contains the custom component.

                          I'm not sure about some of your other questions. I'm still a little new to Repeaters. See this FB3 help topic: Dynamically Repeating Controls and Containers
                          • 11. Problem about  a new component
                            VarioPegged Level 2
                            Here's a slightly different version based on Greg Lafrance's first code sample that may answer those additional questions you have.

                            In general, I would suggest the following:
                            1. Try and write components that are loosely coupled and are as encapsulated as possible.

                            2. If you look at how components within the Flex framework work, you'll notice that it is mostly parents that set properties on children, not the other way around.

                            3. Look at the logical placement of code that directly affects the component, like showUser() and deleteUser(). I'd put those methods in the component itself, not in the main app. Although an argument can be made that deleteUser() is best suited to be placed in the main app, since you wouldn't have to pass a full reference of the ArrayCollection to the component in order to facilitate deleting from within the component.

                            4. Notice how you can set event metadata in the component that the parent can then listen for. This is also how you can identify the specific component using event.currentTarget.

                            5. In my version I "assemble" the button label within the component, but you could just read it from your data directly. However, it gives you great flexibility if you do assemble it this way.

                            TS
                            • 12. Re: Problem about  a new component
                              CHAOS'|nc. Level 1
                              Exactly what I was looking for. Thanks for the awesome post!
                              • 13. Re: Problem about  a new component
                                dam85 Level 1
                                perfect!!!

                                thanks a lot everybody

                                i have the last question about VarioPegged's code.

                                1. why do you declare a new function public function get person():String and NOT public function person():String (without get), what does mean?

                                Thanks!!
                                • 14. Re: Problem about  a new component
                                  VarioPegged Level 2
                                  Regarding the public getter "person" vs. a public property "person", in general it's good practice to access your private properties via getters and setters. This is part of having an encapsulated design.

                                  You'll notice that I don't have a setter (I would have, but ran out of time). You could use one to ensure that the data that's passed into your component conforms to the specific needs you have for the _person property. Let's say that _person can only contain alpha characters in the String, then you'd check for that in the setter function. If it passes the test, then you can set the private property _person. Of course, you could do this in the init() function as well. However, a setter would allow you to change _person at any time during runtime, not just at the creationComplete event. Because _person is private, you'd have to have some way of accessing it from the outside (if you so desire), hence the public getter "person".

                                  The getter may seem weird, but it's there because I set the private prop _person in the private init() function and needed to get at it from the outside. In any event, it's generally good practice to code this way.

                                  TS

                                  BTW, I noticed a couple redundant imports in the main app that I forgot to take out. Won't affect anything though.
                                  • 15. Re: Problem about  a new component
                                    dam85 Level 1
                                    thanks!!