If I have a variable in one external action script, is it possible for me to access it in another external action script? Also, how would I do that?
Many ways. I have no idea what you mean be 'external,' but if you are talking about two classes, an instance of one of which adds, as a Child, an instance of another you can do one of the following.
If the Child wants to refer to a variable on the parent:
var childvariable = parent.parentvariable
or
var childvariable = MovieClip(parent).parentvariable
note that the parent variable should be declared as a public var in the parent class if the parent is in a different 'package' than the child.
If the parent wants to refer to a variable on the Child:
Child.childvariable = something
or
var newvariable = Child.childvariable
You can refer to a variable on a class (instead of an instance of a class) by first declaring the variable as a static var or static const and the referring to as:
Classname.variable
There are other ways to refer to variables on sibling instances. Maybe you could ask a more specific question.
Related
I need to pull the value of a variable in a child package to the parent package. I can not get this to work.
I can set variables from parent to child using package configurations, but I cant find a way to get child value into parent. I tried using same process I used to set value from parent in child but it does not work.
The posted possible solution from another topic did not solve the problem it just stated it may not be possible. The post was from 2013 and a lot of things change, I wanted to see if this is possible now (without saving a value to an external table or anything like that).
This child package is being used in a lot of spots, many of which would not have the parent variable I am trying to set (it would not exist in the parent variable). So the standard script in the post above would not work. I was hoping for a simple return variable value.
Using the above post as a starting point I updated the C# code to check to see if the variable I am trying to set in the parent package exists first (because it would not always be there), then if so set it.
Below is the code I came up with
// have to do this FIRST so you can access variable without passing it into the script task from SSIS tool box
// Populate collection of variables.
//This will include parent package variables.
Variables vars = null;
Dts.VariableDispenser.GetVariables(ref vars);
// checks if this variable exists, and if so then will set it to the value of the child variable
if (Dts.VariableDispenser.Contains("ParentVar") == true)
{
//MessageBox.Show("ParentVariableExists");
// Lock the to and from variables.
// parent variable
Dts.VariableDispenser.LockForWrite("User::ParentVar");
// child variable
Dts.VariableDispenser.LockForRead("User::ChildVar");
// Apparently need to call GetVariables again after locking them.
// Not sure why - perhaps to get a clean post-lock set of values.
Dts.VariableDispenser.GetVariables(ref vars);
// parentvar = childvar
vars["User::ParentVar"].Value = vars["User::ChildVar"].Value;
vars.Unlock();
}
You can put the variable in the parent package, and let the child package modify it.
Another sure-fire way is to populate a table in the child package and read the table in the parent package.
I've got a little problem.
I'm trying to remove a child called in an other class.
I've called "viseur" in my Engine class like that :
private var viseur:Viseur;
viseur = new Viseur(stage);
stage.addChild(viseur);
Now, in my Puzzle.as class I'd like to removeChild(viseur) when my puzzle is complete.
How do I do to do that ?
I've tried :
Engine.viseur.stage.removeChild(viseur);
But it is not working... (and either Engine.viseur.removeChild(viseur) )
Anyone know how could I do that ?
Thank you very much,
There are two issues at play here:
The call Engine.viseur.stage.removeChild(viseur); does not work because the variableviseur is private to the Engine class. If you wish for it to be accessible to other classes, you need to make it public.
However, the other issue with this is that the viseur variable is not a static variable either. So accessing it like this, Engine.viseur.stage.removeChild(viseur); is still incorrect even if you fix the variable to be public. if you wish to access it via another class, you can either 1) pass a reference of the instance of the Engine class to your other class so that it can access the viseur variable or 2) make the viseur variable a static variable, but remember if you do this, that means you can only ever have one Viseur object named viseur.
I have a fairly big swf right now with a bit of coding already. Most vars are created in the root, but now I have a problem.
I want to reload the flash swf (reset), and for that, I need to create a function that destroys all the vars and another one that creates them. At the moment, I have a javascript function that reloads the page, but that really isnt a good solution.
The problem is that when I create a var inside a function, it doesn't get created in "MovieClip(root)", and instead is only related to the function, thus rendering my swf unable to work.
Is there a way to create vars in MovieClip(root) from within a function? Or is there an alternative to what I'm trying to do?
EDIT: Added some example code.
function SetVar():void{
var test:String= new String("foobar");
}
SetVar();
trace(test);
...and the output is:
Scene 1, Layer 'Layer 1', Frame 1, Line 7 1120: Access of undefined property test.
Which is normal, because the "var test" is not global, so it was lost when the function ended. I want to make it so the function "SetVar()" adds the vars to the root, or global.
You need to read up on how scope works.
Basically:
An object declared within another object (be it a Class, Function, Object, or Loop), is only available within that specific object or loop iteration.
Object scope is inherited by children, not by parents. So a function within a class has access to an object declared within that class, but a class does not have access to an object declared within a function
A parent (or any other object) can access objects declared within child classes, but only if it is a public object
So looking at those basic rules (they are very, very basic. If you are just starting out, I urge you to do some proper research into object scope in OOP. It is the basis of everything you will do in dozens of languages), you are declaring an object in a function and trying to access it from outside that function. This breaks Rule #1 from above.
Instead, try this:
var test:String;
function setVar():void{
this.test = 'foorBar';
}
trace(test); //output: null (undeclared)
setVar();
trace(this.test); // output: fooBar
Looking at this, I did two things:
I moved the declaration of test into global space, meaning any object in that object will have access to it
I renamed SetVar to setVar. This has nothing to do with your question, but in AS3, the standard naming conventions dictate you use lowerCaseCamelCase for all objects (including functions), UpperCaseCamelCase for all Class names, and lowercasename for all package names. Again, unrelated but it is good to learn.
Now, ideally, you would probably want to do that setVar function slightly differently. To allow for better abstraction (basically making your code as generic an reusable as possible), you would want to return the value from the function rather than manually set the variable in the function.
var test:String;
var anotherTest:String;
function setVar():String {
return 'foorBar';
}
this.text = setVar();
this.anotherTest = setVar();
trace(this.test); // output: fooBar
trace(this.anotherTest); // output: fooBar
So that allows you to use that function with any String variable imaginable. Obviously, that is not very useful here since it doesn't do any logic. But I am sure you can see how that could be expanded with more code to make it more dynamic and much more useful
EDIT: As an afterthought, I used the this keyword. In AS3 (and a few other languages), this refers to the scope of the current class (or current frame, in case of timeline frame coding). So this.test refers to a variable test declared in the scope of the frame or class.
I am not entirely sure what you are looking for because there is no code associated with your question. However I will impart a bit of information I feel relates to the subject.
if you declare your variables in the class then you can reference them from a function as such:
package{
import flash.display.MovieClip;
public class DocumentClass extends MovieClip{
public var example:String = 'dog';
public function DocumentClass(){
trace(example); // dog
testFctn();
trace(example); // frog
}
public function testFctn(){
example = 'frog'
}
}
}
if you want to reference the variable of a parent class this.parent['variableName'] can be useful too. or a sibling of your working class sharing a parent class, this.parent['childClass']['variableName'] ...
Since you are declaring the variable within the function, its scope is restricted to that function only.
Try declaring the variable outside the function and initializing it in the function instead.
You should then be able to access it from root.
But if you wish to declare a variable on root from within a function (highly unusual requirement) then you can try doing:
document["variableName'] = value;
or
root["variableName'] = value;
inside the function.
Let's say I have many instances of 'Item'.
Later, I want to change some of them to 'SpecialItem' which extends 'Item'.
Can I replace the instance of Item by an Instance of SpecialItem, without having to update all existing references to the old instance of Item?
...So i'd like to do
this = this as SpecialItem
But ofcourse, you can't do that with 'this' ;)
You can only cast backwards, or 'up' the inheritance chain. Something like:
var item:Item = mySpecialItem as Item;
If you need more advanced runtime swapping abilities, think about using composition instead of inheritance, eg, referencing your items as Interfaces instances instead of Class instances.
However, as #IronBCC says, if you are just looking to swap properties, you can do so by making the property public.
No, your can't do this.
But you may use such construction:
class Link {
private var _link:*;
public get link(){}
public set link...
}
and user link.link, to get your Item, and link.link = new SpecialItem(), to set new value.
Rather than use a hard-coded switch statement where you pass it the string name of a class and it then instantiates the appropriate class, I'd like to pass the actual name of the class to my factory method and have it dynamically create an instance of that class. I thought it would be trivial and am surprised it is not working. I must be missing something quite basic:
sample code:
createProduct(50, "Product1Class");
createProduct(5, "Product2Class");
private function createProduct(amount:uint, productClassName:String):void {
var productReference:Class;
try {
productReference = getDefinitionByName(productClassName) as Class;
for (var i:uint = 0; i < amount; i++) {
var product = new productReference() as ProductBaseClass; // throws reference error!
}
} catch (error:ReferenceError) {
throw new ReferenceError(error.message + " Have you linked a library item to this class?");
}
}
The only thing that may be a little odd (not sure) is that these "products" are actually linked Library items (ie: I have a movieClip in the Library that has a linkage to Product1Class and another to Product2Class both of which extend ProductBaseClass, which in turn extends MovieClip.
Why the ReferenceError?
If you have a runtime loaded library then the Class's are not compiled into the main swf, so you get the runtime reference error when you try to create them.
To work around this you can declare "dummy" vars of the classes you want to compile, or if using the flex compiler there are options to include the classes you are missing.
e.g. declare these anywhere in your project
private var p1:Product1Class;
private var p2:Product2Class;
Its a frustrating problem, if your classes extend MovieClip which is a dynamic class you might be able to access the properties etc by doing something like this:
var product:MovieClip = new productReference() as MovieClip;
p1["someCustomProperty"]; //Dot notation might work here as it is a dynamic class
Chris is absolutely right, the ReferenceError is actually being thrown during the call to getDefinitionByName, meaning that the reflection method cannot find Product1Class or Product2Class in your application domain. You can always check if a definition is available by checking the application domain directly, like:
// inside your createProduct method, yields 'false'.
ApplicationDomain.currentDomain.hasDefinition( productClassName );
Are these library assets loaded in at runtime? If so, you can either make sure that the library swf is loaded into the current application domain by adding an appropriately configured LoaderContext to your Loader, or you can replace the call to getDefinitionByName with the loaded swf's application domain's getDefinition method.
getDefinitionByName() and ApplicationDomain.currentDomain.hasDefinition() require full qualified class names. The example code in the original post works when Product1Class and Product2Class are in the default package. However, if you move the product classes to another package, you have to make sure that you are supplying the fully qualified class name to getDefinitionByName().
So if we put our product classes in com.example.products, then the call becomes:
productReference = getDefinitionByName("com.example.products.Product1Class") as Class;
I'm not really sure what the best practice is with this kind of dynamic factory class, but what I ended up doing (since all products were in the same package) was to create a constant within my factory class that defines the package for my products:
private const PRODUCT_PACKAGE:String = "com.example.products."; // note the trailing period
So that way your client code doesn't need to know (nor define) the product package. You just prepend this constant to your product class name when using getDefinitionByName().