String as a function name in as3 / Flex
I have a custom component that extends the spark list.
Inside that custom list, I'm looking to declare a public function that can be called from the main application to filter the result of the list using filterFunction.
My problem is I have multiple filters and I need to pass the function name from the main application as a string ( Or by another way I will learn today! :-) ) like this :
My custom list
<s:List xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/开发者_开发问答flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" dataProvider="{listView}">
<fx:Script>
<![CDATA[
public function applyFilter(functionName:String):void
{
listView.filterFunction = functionName as Function // <-- THIS DOESN'T WORK;
listView.refresh();
}
private function myFilter(obj:Object):Boolean
{
// Execution code
}
private function anotherFilter(obj:Object):Boolean
{
// Execution code
}
]]>
</fx:Script>
Call from my main app
<fx:Script>
<![CDATA[
private function callMyCustomListFilter():void
{
myCustomList.applyFilter('myFilter');
}
]]>
No error, nothing. The filterFunction is just not executed... Can somebody help? Thanks a lot!
My problem is I have multiple filters and I need to pass the function name from the main application as a string
Pass the function as a function. Your apply filter function would be something like this:
public function applyFilter(functionName:Function):void
{
listView.filterFunction = functionName;
listView.refresh();
}
Then your parent container of the list would have something like this:
public function myFilter(item:Object):Boolean{
}
private function callMyCustomListFilter():void
{
myCustomList.applyFilter(myFilter);
}
I didn't notice you had the filter functions inside the list component. But, you can make them public and pass them in the same way:
public function applyFilter(functionName:String):void
{
listView.filterFunction = functionName as Function // <-- THIS DOESN'T WORK;
listView.refresh();
}
public function myFilter(obj:Object):Boolean
{
// Execution code
}
public function anotherFilter(obj:Object):Boolean
{
// Execution code
}
]]>
And this:
<fx:Script>
<![CDATA[
private function callMyCustomListFilter():void
{
myCustomList.applyFilter(myCustomList.myFilter);
}
]]>
Perfect time to use bracket notation.
public function applyFilter(functionName:String):void
{
listView.filterFunction = this[functionName]
listView.refresh();
}
You can also extend this with passing parameters if the need arises.
public function applyFilter(functionName:String, arg1:String,arg2:Number):void
{
listView.filterFunction = this[functionName](arg1,arg2)
listView.refresh();
}
Okay to quickly answer your question, you are probably going to have to map your string functions to your filter functions. Something like this.
public function applyFilter(functionName:String):void
{
var selectedFilterFunction:Function = null;
if( functionName == 'myFilter' )
{
selectedFilterFunction = this.myFilter;
}
else if ( functionName == 'anotherFilter' )
.....
listView.filterFunction = selectedFilterFunction
listView.refresh();
}
You might even be able to get away this doing something like this.
listView.filterFunction = this[ fiterFunctionName ] as Function;
In any case I think you can glean what I am trying to say. You have to find the Function on your class as a property and then you can use it.
Another point you may want to consider is separating out that logic. Generally when I have a filter of some kind, I apply it in the model or the presenter depending on the basis of the filtering. I generally never filter in a view class.
精彩评论