Okay so I have a function called changeHandler - it is called by several eventListeners in other functions. I want to write several if statements that evaluate the source of function call and change the dataProvider of my ComboBox depending on the originating function. Example: one of the many functions is called displayCarbs() and has an eventListener like so:
function displayCarbs(event:MouseEvent):void {
myComboBox.addEventListener(Event.CHANGE, changeHandler);
}
(I've removed all of the unnecessary code from the function above)
The if statement inside the changeHandler will look something like this:
if (****referring function = displayCarbs****) {
myComboBox2.dataProvider = new DataProvider(carbItems);
}
I've searched high and low for something that can achieve this, but I just don't have a good enough grasp of AS3 or vocabulary to describe what describe what I mean to get the answer from Google.
The simplest way I can think of... Couldn't you simply create a text string that updates to the name of function before going to changeHandler then in turn changeHandler can check string content and act accordingly..
public var referring_function:String;
function displayCarbs(event:MouseEvent):void
{
referring_function = "displayCarbs";
myComboBox.addEventListener(Event.CHANGE, changeHandler);
}
function displayCarbs(event:Event):void
{
if (referring_function == "displayCarbs")
{ myComboBox2.dataProvider = new DataProvider(carbItems); }
if (referring_function == "displayOthers")
{ myComboBox2.dataProvider = new DataProvider(otherItems); }
// etc etc
}
I cant remember right now if you need == or just = when checking the If statement against strings.
I know there is an accepted answer already, but based on what I gleaned about the problem, here is a solution that wouldn't require adding another variable to check :
function displayCarbs(event:MouseEvent):void
{
myComboBox.addEventListener(Event.CHANGE, changeHandler);
}
function changeHandler(event:Event):void
{
var comboBox:ComboBox = event.target as ComboBox;
if (comboBox.dataProvider == uniqueProvider)
{
myComboBox2.dataProvider = new DataProvider(appropriateItems);
}
}
This should work if the second dataProvider is determined based on the first dataProvider. This of course requires that your uniqueProvider is a class member variable so it has scope within the handler.
Related
Basically I want to check if a user exists in a database using AMF (and that works great!). But then I want to return the boolean value to another function (in another class) that originally called the "checkUserExistance" function. But, since the database connection isn't immidiate, this function will always return a false value (even if "result" is true). So I would like to have the return-line inside the "onUserChecked"-function but that of course gives me an error. I thought I could create an eventListener, but then, the "return userExists"-line would also have to be inside another function, which doesnät work(?)... What can I do?
public function checkUserExistance(username:String) {
var responderBOOLEAN:Responder = new Responder(onUserChecked, onFault)
var userExists:Boolean = false;
connection.connect(gateway);
connection.call("User.checkUser", responderBOOLEAN, username);
connection.close();
function onUserChecked(result:Boolean):void {
userExists = result;
}
return userExists;
}
I'm sorry but you are trying to force an Asynchronous call to a Synchronous one and this is WRONG.
See here
You should learn how to handle events in the correct way.
What can i suggest you that helped me a lot is this
The only true answer here is to save userExists as a member variable, and dispatch event when the server returns you a response. The client side of the things should be similar to:
// add listener, ServerEvent is a custom event (see below)
server.addEventListener(ServerEvent.CHECK_RESPONSE, onCheckResponse);
server.checkUserExistance('username'); // start the query
function onCheckResponse(e:ServerEvent):void {
if (e.userExists) {
}
}
// inside server class
function onUserChecked(result:Boolean):void {
userExists = true;
dispatchEvent(new ServerEvent(ServerEvent.CHECK_RESPONSE, userExists));
}
/* ServerEvent is a custom class that extens Event
Such classes are used so you can pass special properties in them
via constructor (pass data, store it into member variable)
and through getter for that variable.
If you don't like it, simply add/dispatch Event.COMPLETE
and use public property to get userExists from server
*/
I used to work on AS2 and make games, and now I wanna learn AS3 and have all its nice features (using Flash CS IDE). Now I m trying to rewrite a function to discard it.
function something():void{
//do something
}
function something():void{}
like this. please help or just give some alternatives, thanks.
What you're trying to do is very illogical - a function should be defined once and exist always. Not only that, but it should definitely always behave the same way, especially considering AS3 does not support overloading.
AS3 introduces the OOP paradigm for you to use - this further emphasises the above - you should create classes which define a fixed collection of properties and methods. This way, the intent of each class in your application is clear, and what you expect something to be able to do won't change.
If you absolutely must be able to delete functions, you can assign them to a dynamic object and remove or redefine them with the delete keyword:
var methods:Object = {
something: function():void
{
trace('Still here.');
}
};
methods.something(); // Still here.
delete methods.something;
methods.something(); // TypeError: something is not a function.
methods.something = function():void
{
// Define new function.
}
Or assign an anonymous function to a variable of type Function, from which point you can set the reference to null:
var something:Function = function():void
{
trace("Still here.");
}
something(); // Still here.
something = null;
something(); // TypeError: value is not a function.
something = function():void
{
// Define new function.
}
Can anyone tell me how to make a function that works like below in ActionScript3.0?
function test(one:int){ trace(one);}
function test(many:Vector<int>){
for each(var one:int in many){ test(one); }
}
You can use an asterisk and the is keyword:
function test(param:*):void
{
if(param is int)
{
// Do stuff with single int.
trace(param);
}
else if(param is Vector.<int>)
{
// Vector iteration stuff.
for each(var i:int in param)
{
test(i);
}
}
else
{
// May want to notify developers if they use the wrong types.
throw new ArgumentError("test() only accepts types int or Vector.<int>.");
}
}
This is seldom a good approach over having two sepaprate, clearly labelled methods, because it can be hard to tell what that methods' intent is without a specific type requirement.
I suggest a more clear set of methods, named appropriately, e.g.
function testOne(param:int):void
function testMany(param:Vector.<int>):void
Something that could be useful in this particular situation is the ...rest argument. This way, you could allow one or more ints, and also offer a little more readability for others (and yourself later on) to understand what the method does.
function test(many:*):void {
//now many can be any type.
}
In case of using Vector, this also should work:
function test(many:Vector.<*>):void {
//now many can be Vector with any type.
}
Hello i have a function as following:
private function seatClickHandler(e:MouseEvent):void{
var check:Check = new Check();
if(e.target.contains(check)){
e.target.removeChild(seat);
}else{
e.target.addChild(check);
}
}
basicly i want to check if e.target contains a child called check. If it does i want e.target to remove the child, else i want to add the child. But the method i tried doesnt seem to work although i think this is the way to go. Any suggestions?
When you declare your Check object, Actionscript creates a reference code for that specific object.
So the first time your code is run, your Check object could be given a reference of #c0ecc29. Your if statement checks to see if #c0ecc29 is a child component of target. It won't be, so the Check object with reference #c0ecc29 is added to target.
The second time the clickHandler is called, a new instance of the Check object is created which will have a new reference id. Your target has the original Check object with the #c0ecc29 reference so it won't get removed.
The correct way to get this working depends on what target is (DataGrid, Group, etc.).
EDIT:
Based on your comments, I would try something like this. It checks to see if the Check object is a child of target and adds it if needed. Then when the Check object is clicked, it will toggle its visibility.
public var check:Check = new Check();
private function seatClickHandler(e:MouseEvent):void
{
if(!e.target.contains(check))
{
check.addEventListener(MouseEvent.CLICK, check_handleClick);
e.target.addChild(check);
}
}
protected function check_handleClick(event:MouseEvent):void
{
check.visible = !check.visible;
}
If you need to actually remove the Check object from target instead of just changing its visibility, you could try this:
public var check:Check = new Check();
private function seatClickHandler(e:MouseEvent):void
{
if(!e.target.contains(check))
{
e.target.addChild(check);
}
else
{
e.target.removeChild(check);
}
}
If the child is named 'check' then you should be able to use getChildByName(). See flash.display.DisplayObject.name
If you happen to have the child in memory, you can use getChildIndex()
check is a new object in the scope of that function, so it will not be a child of the event target.
What you want to do is declare check as a global variable (And also cast target as DisplayObjectContainer).
e.g.
private function seatClickHandler(e:MouseEvent):void{
if((e.target as DisplayObjectContainer).contains(check)){
(e.target as DisplayObjectContainer).removeChild(seat);
}else{
(e.target as DisplayObjectContainer).addChild(check);
}
}
However I'm not sure if this is exactly what you want to do (There can only be one check). A better approach would be to have a function (maybe toggleCheck) on the target, and have that display object responsible for rendering the check (And removing it)
This worked perfectly fine for me in my situation:
if(possibleChild.parent == holder)
holder.removeChild(possibleChild)
It may or may not be exactly what you're looking for.
I'm pretty positive what I want to do isn't possible with ActionScript, but it would be nice to be wrong.
I need to pass a variable reference to a function, and have the function change the value of the variable.
So, simplified and not in completely correct syntax, something like this:
function replaceValue(element:*, newValue:String):void
{
element = newValue;
}
var variableToModify:String = "Hello";
replaceValue(variableToModify, "Goodbye");
trace(variableToModify) // traces value of 'Hello', but want it to trace value of 'Goodbye'
Of course, in the replaceValue function, element is a new reference to fungibleValue (or, rather, a new reference to fungibleValue's value). So, while element gets set to the value of newValue, fungibleValue does not change. That's expected but totally not what I want, in this case.
There's a similar question, for Ruby, here Changing value of ruby variables/references
As the question points out, Ruby has a way to accomplish this. BUT is there any way to do this in ActionScript?
If so, it's going to make something stupid a lot easier for me.
No it's not possible the function will always get the value and not the reference. But if you are able to call replaceValue why not returning the new value from your function :
function replaceValue(element:*, newValue:String):String
{
// .. do your work
return newValue;
}
var variableToModify:String = "Hello";
variableToModify = replaceValue(variableToModify, "Goodbye");
trace(variableToModify)
If you pass an Object or a Class, you can modify one fiels based on his name as :
function replaceValue(base:Object, fieldName:String, newValue:String):void {
// do your work
base[fieldName] = newValue;
}
var o:Object={ variableToModify:"Hello" };
replaceValue(o, "variableToModify", "Goodbye");
trace(o.variableToModify);