(This tag must be placed inside an <EventHandlers> tag, <MessageHandlers> tag or <Injectors> tag)
MethodInvoker is one of the most used tags. When placed inside a EventHandlers tag and the list of handlers is executed, it will create an object of the class specified in the "generator" attribute. It will then call the function specified in the "method" attribute on the newly created object. You can pass arguments to this function that come from a variety of sources, such as the event itself, a server result object, or any other value. Unless you specify cache="none", this object instance will be "cached" and not instantiated again.
Example:
<MethodInvoker
generator="ClassNameToInstantiate"
method="methodToExecute"
arguments="{['argument1', 'argument2']}" />
The above example would be the same as doing the following in ActionScript code:
var myWorker:ClassNameToInstantiate = new ClassNameToInstantiate(); myWorker.methodToExecute('argument1', 'argument2');
The main difference is that in the case of the MethodInvoker, the object is created and the function executed whenever the list of handlers is run and in the order specified in the list.
Note: To call static methods, methods on a singleton object, or on an object that has been created elsewhere, use the InlineInvoker tag instead.
Attributes
generator
required
The generator attribute specifies what class should be instantiated and run.
Suppose you have a class called "MyWorker" in the package com.yourdomain.business. You can specify a complete path to com.yourdomain.business.MyWorker:
<MethodInvoker
generator="com.yourdomain.business.MyWorker"
method="methodToExecute"
arguments="{['argument1', 'argument2']}"/>
Generally you may want to use a binding to specify the class name. Assuming you have an import statement like this in your Event Map:
import com.yourdomain.business.MyWorker;
or simply:
import com.yourdomain.business.*;
You can then instantiate your object using bindings:
<MethodInvoker
generator="{MyWorker}"
method="methodToExecute"
arguments="{['argument1', 'argument2']}"/>
The advantage of using this syntax is that if you are using Flex Builder, you can press the command key (Mac) or the Ctrl key (Windows) and click on the generator class (MyWorker in the example) and it will take you to the class definition.
method
The method attribute specifies what function to call on the created object. If your class MyWorker contains a function called doWork(), you would then write:
<MethodInvoker
generator="{MyWorker}"
method="doWork"
/>
arguments
If the function in your class has arguments, you can pass them via the "arguments" attribute. Suppose your doWork function has the following signature:
public function doWork(name:String, value:Number)
then you can pass those arguments as follows:
<MethodInvoker
generator="{MyWorker}"
method="doWork"
arguments="{['Tom', 36]}"/>
Note that the arguments attribute expects an array. Besides passing literal values, you can pass values coming different sources. See Passing Arguments
cache
either "global", "inherit", "local" or "none"
The cache attribute lets you specify whether this newly created object should be kept live so that the next time an instance of this class is requested, this already created object is returned instead.
For example, say you have two sets of event handlers that want to use the same instance of an object. Since the default value for this attribute is "inherit", it will do that by default. On the other hand, if you wanted to have two different instances, then you must set this attribute to "none".
The value "inherit" will globally cache the object in a normal EventMap and it will locallly cache the object in a LocalEventMap. If you want to cache globally in a LocalEventMap so that the object can be accessed from other event maps, set the value to "global".
<EventHandlers type="myEventType">
<MethodInvoker
generator="{MyWorker}" method="doWork"
cache="false" />
</EventHandlers>
<EventHandlers type="myOtherEventType">
<MethodInvoker
generator="{MyWorker}" method="doDifferentWork"
cache="false" />
</EventHandlers>
constructorArguments
Array
If the constructor of you class requires arguments, you can pass them via the "constructorArguments" attribute. Suppose your constructor has the following signature:
public function MyWorker(name:String, value:Number)
then instantiating the class as follows will work:
<MethodInvoker generator="{MyWorker}"
constructorArguments="{['Tom', 36]}"
method="doWork"/>
Inner tags
Properties
You can add properties to your object by using the Properties tag inside the MethodInvoker tag. These properties will be set before calling the function specified in the "method" attribute, so you can be sure that those properties will be available when the function is executed. These properties must be public.
Suppose you are creating an instance of a ShippingCalculator class. This class has a property called weightFactor and flatFee. In order to set those two properties, you can use the <Properties> inner tag. As attributes of the Properties tag, you can specify the names of your properties and set the values of those properties by setting the value of those attributes as follows:
<MethodInvoker
generator="{ShippingCalculator}"
method="calculateShipping" .... >
<Properties weightFactor="0.5" flatFee="3" />
</MethodInvoker>
Besides specifying literal values, you can assign values coming from the event that triggered the handlers:
<MethodInvoker
generator="{ShippingCalculator}"
method="calculateShipping" .... >
<Properties weightFactor="{event.factor}" flatFee="{event.fee}" />
</MethodInvoker>
This assumes that the original event contained a factor property and a fee property.
If this MethodInvoker tag is inside a
<resultHandlers> tag that originated from one of the service invoker
tags, you can also pass values coming from the server result:
<RemoteObjectInvoker .....service attributes....>
<resultHandlers>
<MethodInvoker
generator="{ShippingCalculator}"
method="calculateShipping" .... >
<Properties weightFactor="{resultObject.factor}" flatFee="{resultObject.fee}" />
</MethodInvoker>
</resultHandlers>
</RemoteObjectInvoker>
This assumes the server returned an object that contained a factor property and a fee property.
If this MethodInvoker tag is inside an
<faultHandlers> tag that originated from one of the service builder tags,
you can also pass values coming from the server fault. This comes in handy when
you want to handle possible server errors.
<RemoteObjectInvoker .....service attributes....>
<faultHandlers>
<MethodInvoker
generator="{MyErrorHandler}"
method="handleShippingError" .... >
<Properties myErrorProperty="{fault.faultDetail}" />
</MethodInvoker>
</faultHandlers>
</RemoteObjectInvoker>
You can also use the complete resultObject, fault or data as a property depending on what your event properties are.
For example, if the server returned a number with the value of the flat fee, you would be able to set the property "flatFee" with the server result:
<MethodInvoker
generator="{ShippingCalculator}"
method="calculateShipping" .... >
<Properties flatFee="{resultObject}" />
</MethodInvoker>
You can use the service fault:
<MethodInvoker
generator="{MyErrorHandler}"
method="handleShippingError" .... >
<Properties error="{fault}" />
</MethodInvoker>
You can also use the sequence data. The data property must be of type Object.
<MethodInvoker
generator="{ShippingCalculator}"
method="calculateShipping" .... >
<Properties myProperty="{data}" />
</MethodInvoker>
Finally, you can use the lastReturn
<MethodInvoker
generator="{ShippingCalculator}"
method="calculateShipping" .... >
<Properties myProperty="{lastReturn}" />
</MethodInvoker>
We actually had that in previous versions. In the current version, that functionality has been transferred to the InlineInvoker tag.
If you have several event maps, they would all share the same model if you specify cache="true", which is the default value.
The example that you give about a Multiple Document Interface would require more work, but it is possible to achieve. Most likely, there would be a "Tab Manager" that would take care of passing/storing the corresponding document to the tabs (instead of trying to access the specific model from the event map).
Let's presume, I've a class and it's constructor needs a parameter, how can I use the methodinvoker in this case?
i.e.
var repo:IRepo = new DjangoRepo("http://localhost:8000");
repo.getMedia( ... )
do I have set a setter for the host parameter?
regards,
Viktor
Sorry for the late reply. MethodInvoker also has a constructorArguments attribute that you can use to pass parameters to the constructor. See ObjectBuilder, which has more documentation on that. I'll add the documentation for that here too.
steptan,
That's right, thanks for the correction.
You can also use the sequence data. The data property must be of type Object.
<MethodInvoker
generator="{ShippingCalculator}"
method="calculateShipping" .... >
<Properties myProperty="{data}" />
</MethodInvoker>
<InlineInvoker method="{ getMethodInvokerGenerator }"/>
<MethodInvoker generator="{lastReturn}" method="methodtoCall" arguments="{argument }"/>
I have also tried:
<MethodInvoker generator="{SomeClass}" method="{ getMethodInvokerGenerator }"/>
<MethodInvoker generator="{lastReturn}" method="methodToCall" arguments="{argument }"/>
Both methods give me an error:
Type Coercion failed: cannot convert com.asfusion.mate.core::[email protected] to
How can I make the generator class more dynamic so that I can set it in a function and use the lastreturn value?
Thanks in advance for any help.
<MethodInvoker generator="{SomeClass}" method="{ getMethodInvokerGenerator }"/>
<MethodInvoker method="methodToCall" arguments="{argument }">
<Properties generator="{lastReturn}"/>
</MethodInvoker>
See Using lastReturn