sixtyfootersdude
sixtyfootersdude

Reputation: 27221

Call method in containing class from item renderer

Class Dog. Note that a dog does not know what its location is. Logically the dog should not know its location.

public class Dog { 
    public var name:String;
    public var age:Number;
}

A UI component which displays all the dogs in a list. There is a method to determine if a dog has escaped.

<?xml version="1.0" encoding="utf-8"?>
<s:VGroup ... >
    <fx:Script>
        <![CDATA[
            [Bindable]
            private var listDataProvider:ArrayCollection /* ArrayCollection of Dogs */

            public var hasDogEscaped(dog:Dog):Boolean {
                return ...;
            }
        ]]>
    </fx:Script>
    <s:List id="list" dataProvider="{listDataProvider}" itemRenderer="DogItemRenderer"/> 
</s:VGroup>

An item renderer displaying a dog's name and if a dog has escaped an explanation mark beside the dog's name.

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer ...>
    <s:Label text="{(data as dog).name}" verticalAlign="middle" height="100%"/>

    <mx:Image id="dogEscaped" 
              visible="{???????????????????????????????????????.hasDogEscaped(data as Dog)}"
              source="@Embed(source='/assets/icons/warning.png')"/>
    </s:Group>
</s:ItemRenderer>

What I would like to do is have the item renderer call the hasDogEscaped method from the item renderer but I have not been able to figure out how to do that. Any help would be greatly appreciated.

Upvotes: 0

Views: 456

Answers (5)

1.21 gigawatts
1.21 gigawatts

Reputation: 17736

You can use "outerDocument" to access the document with your method in it. Note: the method must be marked public.

Alternatives, you could put the function on a singleton like, MyDogUtils.hasDogEscaped() and call it when you need it from within the item renderer (99% always on set data override).

Or you could put it in the item renderer as a static method.

Upvotes: 0

Amy Blankenship
Amy Blankenship

Reputation: 6961

You could also do soemthing like this:

protected var escapeAlarm:IEventDispatcher;
[Bindable]
protected var dogItemRenderer:ClassFactory = new ClassFactory(DogItemRenderer);//you can bind to this renderer in your List component or whatever

//call from creationComplete
protected function init():void {
   dogItemRenderer.properties = {alarm: escapeAlarm};//again, you'll need to expose an alarm property on your renderer
}

public function dogHasEscaped(escapee:Dog):void {
  escapeAlarm.dispatchEvent(new DogHasEscapedEvent('escapeAlert', escapee);//will need custom Event Class, post back if you need help
}

Then in your renderer, just compare the escaped dog to the rendered dog. This accounts for dogs that escape after the List has drawn

Upvotes: 0

The_asMan
The_asMan

Reputation: 6402

Item renderer's are for displaying your data only not for application logic.
Since your arrayCollection is already bindable you should add an event listener to it to call hasDogEscaped on change.

Upvotes: 0

Jonathan Rowny
Jonathan Rowny

Reputation: 7588

I wouldn't bind to the function. You don't need to anyway.

override public function set data(value:Object):void{
   if(value){
    super.data = value;
    dogEscaped.visible = yourFunction(data);
   }
}

Now, if you want to pass the non-static version of yourFunction into your dataGrid you need to add it as a property. To do that you'll need to use a ClassFactory to pass a property to your itemRenderer. Basically that looks like this:

 dogItemRenderer= new ClassFactory(DogIteMRenderer);
 dogItemRenderer.properties = {dogEscapedFunction: dogEscapedFunction};
 dogColumn.itemRenderer = dogItemRenderer;

now make sure there's a property called dogEscapedFunction in your itemRenderer.

Upvotes: 2

dtuckernet
dtuckernet

Reputation: 7895

In short - you need to add an isVisible property on the Dog class. While the Dog shouldn't know its location - it does need to know if it is visible. Creating paths into (and out of) an item renderer is generally a bad idea. (If this goes beyond the scope of the Dog class, then you can use the Adapter pattern to wrap the existing class and add the additional property.) The item renderer needs to receive all of the data it needs to properly display what it is rendering.

You can set the value of this property in the MXML file that defines the s:List - and then override the set data method on the item renderer to determine if the Image should be visible.

Upvotes: 0

Related Questions