views:

933

answers:

5

I have a Renderer:

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:mx="library://ns.adobe.com/flex/mx">

  <fx:Metadata>
    [Event(name="addToCart",type="event.ProductEvent")]
  </fx:Metadata>
  <fx:Script>
    <![CDATA[
      import events.ProductEvent;

      import mx.collections.ArrayCollection;


      protected function button1_clickHandler(event:MouseEvent):void
      {
        var eventObj:ProductEvent=new ProductEvent("addToCart",data.price,data.descript);

        dispatchEvent(eventObj);

      }
    ]]>
  </fx:Script>

  <fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
  </fx:Declarations>

  <s:states>
    <s:State name="normal"/>
    <s:State name="hovered"/>
  </s:states>

  <s:BorderContainer >
    <s:layout>
      <s:VerticalLayout paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10"/>
    </s:layout>

    <s:Label text="{data.descript}"/>
    <mx:Image source="{data.url}" width="50" height="50" width.hovered="100" height.hovered="100"/>
    <s:Label text="{data.price}"/>
    <s:Button includeIn="hovered" click="button1_clickHandler(event)" label="buy"/>



  </s:BorderContainer>
</s:ItemRenderer>

and the custom event class:

package events
{
  import flash.events.Event;
  [Bindable]
  public class ProductEvent extends Event
  {

    public var price:String;
    public var descript:String;

    public function ProductEvent(type:String,price:String, descript:String)
    {
      super(type);
      this.price=price;
      this.descript=descript;
    }
    override public function clone():Event
    {
      return new ProductEvent(type,price,descript);

    }
  }
}

but i cannot call that event in a container from the main application

<s:SkinnableDataContainer id="Sk" x="200" y="300" left="100" right="900" dataProvider="{imagesCollection}" itemRenderer="components.ImageRenderer" includeIn="normal"   >
    <s:layout>
      <s:TileLayout/>
    </s:layout>

  </s:SkinnableDataContainer>

any ideas?

thanks

A: 

It's hard to make out what you're trying to do from the question, because of the formatting, and it appears there's some text missing.

However. try making the event bubble, and add the event listener on the list which holds the itemRenderers.

Eg:

 <mx:Canvas creationComplete="list1.addEventListener('addToCart',onAddToCart)">
    <mx:List id="list1" itemRenderer="com.foo.YourItemRenderer" />
 </mx:Canvas>


 <!-- YourItemRenderer.mxml -->
 <mx:Canvas>
      <!-- Other item renderer stuff -->
       <mx:Button click="dispatchEvent(new ProductEvent('addToCart'))" />
 </mx:Canvas>


 // ProductEvent.as
 public class ProductEvent {
    public function ProductEvent(type:String,bubbles:Boolean=true) {
         super(type,bubbles);
         // ... etc
    }
 }
Marty Pitt
A: 

Events are not called, so I'm not entirely sure what you want.

You can create an instance of an event class, like this:

var myEvent : ProductEvent  = new ProductEvent();

You can dispatch that event from an itemRenderer the same way you would do so if you were using an event elsewhere:

dispatchEvent(myEvent);

You can also add an event listener to run some code when is dispatched:

this.addEventListener(ProductEvent.someConstant, onProductEvent);

And at some other point in the code, you'd have you're listener function like this:

public function onProductEvent(e:ProductEvent):void{
// do stuff
}

In an itemRenderer, you often want to make your event bubble so that it can be listened to on the component which uses renderers--usually a list based class.

If you fix your code it may be easier to get a feel for what you're trying to do.

www.Flextras.com
A: 

Perhaps this is a little out of scope, but that sort of signaling with events is where MVC frameworks like Cairngorm shine. I usually think of them as AS event buses.

mezmo
A: 

I want to make this:

<s:SkinnableDataContainer id="Sk" x="200" y="300" left="100" right="900" dataProvider="{imagesCollection}" itemRenderer="components.ImageRenderer" includeIn="normal" ***addToCart=something(event)*** >
john
A: 

This is possible using the Event metadata tag: http://livedocs.adobe.com/flex/3/html/help.html?content=createevents_3.html

You'll have to sub-class SkinnableDataContainer and add the metadata tag:

[Event(name="addToCart", type="events.ProductEvent")]
public class MySkinnableDataContainer extends spark.components.SkinnableDataContainer
{
}

You can also do it in MXML:

<?xml version="1.0"?>
<!-- ../MySkinnableDataContainer.mxml -->
<s:SkinnableDataContainer xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <mx:Script>
    <![CDATA[
        import events.ProductEvent;
    ]]>
    </mx:Script>

    <mx:Metadata>
        [Event(name="addToCart", type="events.ProductEvent")]
    </mx:Metadata>

</s:SkinnableDataContainer>

Then use this new class instead of the SkinnableDataContainer:

<MySkinnableDataContainer id="Sk" x="200" y="300" left="100" right="900" dataProvider="{imagesCollection}" itemRenderer="components.ImageRenderer" includeIn="normal" addToCart="something(event)" />

Note: depending on your events bubble property you may have to catch it and then re-forward it along inside of MySkinnableDataContainer.

James Fassett
so i can't use a custom event as property from an item renderer? because i can from a custom component
john
It is a custom event - a ProductEvent like in your example. You just have to declare it as an event using the metadata tag to expose it using MXML.
James Fassett