use getter setter with static function - actionscript-3

I try to use getter/ setter with static function.
Inside a mxml file, I try to get http service like that :
EventColorByDayModel.acListeVac(event.result.ListeVac.VacPeriode);
Indeed, I need to use result to poulate arraycollection inside EventColorByDayModel.
See, below all my class:
package
{
import mx.collections.ArrayCollection;
public class EventColorByDayModel
{
private static var _acListeVac:ArrayCollection;
public static function get acListeVac():ArrayCollection
{
return _acListeVac;
}
public static function set acListeVac(value:ArrayCollection):void
{
_acListeVac = value;
}
public static function getEventColorByDate(date:Date):uint
{
var result:uint = 0xE3EBF6;
// Store renderer
for each ( var item:Object in _acListeVac )
{
if (( item.dateMySQLDeb.time <=date.time )&&( date.time<=item.dateMySQLFin.time ))
result = uint(item.sColor);
}
return result;
}
public function EventColorByDayModel()
{
}
}
}
But, in that case, an error appear with message, "impossible to access to acListeVac with a ref static Class".
I try to translate message error french to english. I hope, it's comprehensive.
Thanks for helping.

Because it is a setter (specified by the set keyword), you just set the value like any other variable. So try this instead of the first line of code you have up there:
EventColorByDayModel.acListeVac = event.result.ListeVac.VacPeriode;

Related

Why do I get a 0 width for a class instantiated by static variable

Here is a Monitor class. I am trying to get it's width, through it's static property. So that, to get width, I can write : Monitor.width, Monitor.height
However, when I instantiate, it through a static variable, the instantiation is successful, but still returns a 0 value width. Is their any alternative way ( other than instantiating it inside the get width and get height method itself ) ?
package {
import flash.display.*;
public class Monitor extends MovieClip {
private static var staticInstance: Monitor = new Monitor();
public function Monitor() {
}
static public function get width(): Number {
// staticInstance: Monitor = new Monitor() <<< this will work
return staticInstance.width;
}
static public function get height(): Number {
// staticInstance: Monitor = new Monitor() <<< this will work
return staticInstance.height;
}
}
}
When trying :
trace(Monitor.width) // output is 0
You shouldn't do this with a display list type. Static code gets executed when your class gets initialized by virtual machine (i.e. in internal Monitor$cinit() method), and it will not create visuals for you. Try placing trace(this.width); in Monitor constructor and see that it returns zero with your approach.
If you are absolutely sure, that you need a singletone here (which is not the case most of the time), use the "classic" idiom:
package
{
import flash.display.MovieClip;
public class Monitor extends MovieClip
{
private static var instance : Monitor;
public static function getInstance()
{
if (instance == null) {
instance = new Monitor();
}
return instance;
}
public static function get width()
{
return getInstance().width;
}
public function Monitor()
{
trace("Monitor constructor: "+this.width);
}
}
}
When you do:
trace("Monitor.width = "+Monitor.width);
The output should be:
Monitor constructor: some_number
Monitor.width = some_number
That is correct since static variables are computed before anything else when your program starts so a graphic object can't really have any size at this point.
The correct way to deal with this is to delay the instantiation with a classic getInstance() for example:
private static var staticInstance: Monitor;
No instantiation to start with then:
static private function get instance():Monitor
{
if(!staticInstance)
{
staticInstance = new Monitor();
}
return staticInstance;
}
Now use this getter in all your calls:
static public function get height(): Number
{
return instance.height;
}

Error: Call to a possibly undefined method getRegionNameForCountries through a reference with static type com.framework.model:CountryModel

Trying to figure out why I can call this function from a instantiated version of this class.
The error I get is this:
Error: Call to a possibly undefined method getRegionNameForCountries through a reference with static type com.framework.model:CountryModel.
The error comes from this code:
public static function territoriesFunction( item:Object, column:DataGridColumn ):String
{
return RemoteModelLocator.getInstance().appModel.countryModel.getRegionNameForCountries( item.countriesAvailable ) + ' ('+ item.countriesAvailable.length.toString() + ')';
}
The Class I'm trying to call the function from is here:
package com.framework.model
{
import com.adobe.cairngorm.vo.IValueObject;
import com.adobe.crypto.MD5;
import com.vo.RegionVO;
import flash.utils.ByteArray;
import mx.utils.ObjectUtil;
public class CountryModel implements IValueObject
{
public static function getCountriesForRegion( regionName:String ):Array
{
try
{
var result:Array = _dataModel[regionName];
}
catch(e:Error){}
result = ( result )? result: _dataModel[CountryModel.WORLDWIDE];
return ObjectUtil.copy( result ) as Array;
}
public static function getRegionNameForCountries( countries:Array ):String
{
if( !countries || !countries.length )
{
return CountryModel.WORLDWIDE;
}
countries.sortOn("name");
var buffer:ByteArray = new ByteArray();
buffer.writeObject(countries);
buffer.position = 0;
var hash:String = MD5.hashBytes( buffer );
try
{
var regionName:String = _dataModel[hash];
return ( regionName && regionName.length )? regionName : CountryModel.CUSTOM;
}
catch( e:Error )
{
}
return CountryModel.CUSTOM;
}
}
}
You can only access static vars/method from the Class object itself (eg. MyClass.method()), or from within the class declaration (static or instantiated).
Here is a simplified example:
MyClass.staticFunction(); //allowed
var myInstance = new MyClass();
myInstance.staticFunction(); //NOT allowed
//inside the MyClass.as
this.staticFunctionInSameClass(); //allowed
What you are trying to do is access a static method from a reference to an instantiated object of that class.
To keep the same structure as you are currently doing, you either need to create a non static helper method in the class:
//CountryModel class
public function getRegionNameForCountriesHelper(countries:Array):String
{
return getRegionNameForCountries(countries); //calls the static method
}
OR just access it on the class itself.
return CountryModel.getRegionNameForCountries(item.countriesAvailable, ....);
If the Class is not known ahead of time, you can do it by casting the instance as Object, then accessing the constructor property which returns a reference to the Class.
return (Object(RemoteModelLocator.getInstance().appModel.countryModel).constructor).getRegionNameForCountries(item.countriesAvailable, ...);
That way is very messy though, without compile time checking.
I would recommending either making the class static only (don't allow instantiation), or don't use static methods in it. Without knowing what all those parts of your application are (eg. RemoveModelLocator, appModel) it's difficult to say what would be best for your circumstance.

Action Script Convert Function to an Object

I need to convert a function to an object. For example, when I need to use the variable called fn I want to be able to use it as a function fn() or as an object fn.json(). I have code to do it, but I think it's not correct.
package lib.smartic {
// import
import lib.smartic.smartic;
// constructor $
public var fn = function(s):smartic{
return new smartic(s);
};
Function.prototype.json = function (s) {
// call
};}
How can I apply the prototype to my variable fn, not just to the object class?
Actually, Function is an Object... and as said #The_asMan, you shouldn't use prototypes.
Simple example:
var smartic: Smartic = new Smartic("someValue");
trace(smartic.json());
And definition of your Smartic class, without prototypes:
public class Smartic {
private var _value:String;
public function Smartic(value:String) {
_value = value;
}
public function json():String {
return "Some json here";
}
}
I don't know what you want to do exactily but if you want smartic to be a function you can do something like this:
keep the code givent by Nicolas Siver and add this function:
public function smarticFunc(value:String):Smartic
{
return new Smartic(value);
}
so you can use smarticFunc as function or as Smartic as it returns a Smartic.

How to access a Class in the default package from a sub package Class in Flash AS3.0

I got error message when trying to access a class in the default package from the class in its sub package. Can any one help me to sort this out.
FYI, my package structure is A -> B. I meant folder 'A' as default package and 'B' as sub package.
Thanks in advance.
Just create a object of Class A, and call class instance method, from its object.
var classAObj:A = new A();
classObj.MethodA();
I think what you're looking for is for class B to extend class A. That would look something like this in your code:
package main
{
class B extends A
{
// Code here...
}
}
Having code inside packages does not in general affect functionality, it's more an organizational tool. (Except for the internal keyword.)
how about private, protected and public ? I could not see any explanation in the other answers so here it is.
class A
{
private var _password:String;
public var username:String;
protected var serverURL:String;
public function login():void
{
// some code
callServerForLogin();
}
protected function callServerForLogin():void
{
// some code
}
}
class B extends A
{
public function B()
{
var parentPassword = super._password;
// FAILS because private and accessible only inside class A
var parentUsername = super.username
// all ok in here, public property
var parentServerURL = super.serverURL;
// all ok, because it is protected
// also we can call super.login(); or super.callServerForLogin();
}
// IMPORTANT we are also allowed to override public and protected functions
override public function login():void
{
super.login();
// we call the parent function to prevent loosing functionality;
Alert.show("Login called from class B");
}
override protected function callServerForLogin():void
{
super.callServerForLogin();
// keep also parent logic
Alert.show("calling protected method from B");
}
}
// ---- Now considering you declare an object of type B you can do the following
var bObj:B = new B();
// access public properties and call public functions from both B and A
bObj.username = "superhero";
bObj.login();
// will get compile error for next lines
bObj.serverURL = "host.port";
bObj.callServerForLogin();

How do I make my public static logging method write to an inputfield?

I figured out how to create a static method that is available everywhere, for example:
UtilLib.as:
package
{
public final class UtilLib
{
public static function getTimeStamp():uint
{
var now:Date = new Date();
return now.getTime();
}
}
}
I can access this everywhere by doing UtilLib.getTimeStamp() - Now, I want to create a new staic method called log(msg:String). This should log a message to a multi-line inputfield.
The problem however is that this inputfield must be created somewhere and must be accessible and visible all the time, and I don't want to pass it through the function parameters all the time as this would cause a lot of trouble (I'd have to pass it through objects aswell..).
So, how do I make a "public textfield" so my static log method can write to it?
UPDATE:
I now tried the following class, with a static constructor (I think). However, the textfield object is not showing. When I do an addChild(debugField) after creating it, it gives me error 1180.
Logger.as
package
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldType;
public class Logger extends Sprite
{
public static var debugField:TextField;
/* static block */
{
trace("Logger initializing.");
debugField = new TextField();
debugField.width = 500;
debugField.height = 100;
debugField.x = 100;
debugField.y = 400;
debugField.background = true;
debugField.backgroundColor = 0xFFFFFF;
debugField.defaultTextFormat = new CustomTextFormat();
debugField.mouseWheelEnabled = true;
debugField.multiline = true;
debugField.type = TextFieldType.DYNAMIC;
}
public static function log(msg:String):void
{
if (debugField) debugField.appendText(msg);
}
}
}
I initialize it like this:
var test:Logger = new Logger();
addChild(test);
And I log a new message like this:
Logger.log("test");
Unfortunately, the textField is not showing.
Essentially you need:
somewhere to log a message which is globally accessible
the ability to update a text field whenever the log message changes
A simple solution using objects could look like this:
Example
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
public class Example extends Sprite {
private var messageLog:TextField;
public function Example() {
createTextField();
MessageLogger.getInstance().addEventListener( MessageLogger.LOG, handleMessageLoggerUpdate );
MessageLogger.getInstance().log( "Message!" );
}
private function handleMessageLoggerUpdate( event:Event ):void {
messageLog.text = MessageLogger.getInstance().getLog();
}
private function createTextField():void {
messageLog = new TextField();
addChild( messageLog );
}
}
}
MessageLogger
package {
import flash.events.EventDispatcher;
import flash.events.Event;
public class MessageLogger extends EventDispatcher {
private static var instance:MessageLogger;
public static function getInstance():MessageLogger {
if ( !instance ) {
instance = new MessageLogger( new InstanceKey() );
}
return instance;
}
public static var LOG:String = "MessageLoader#log";
private var messageLog:String;
public function MessageLogger(key:InstanceKey) {
messageLog = "";
}
public function log( message:String ):void {
messageLog += message;
notify();
}
public function getLog():String {
return messageLog;
}
private function notify():void {
dispatchEvent( new Event( LOG ) );
}
}
}
class InstanceKey {}
The important thing here is that a message can be logged from anywhere using
MessageLogger.getInstance().log( "Your Message Here" );
and anything can be notified of when a message has been logged using
MessageLogger.getInstance().addEventListener( MessageLogger.LOG, listenerFunction );
at any point the current message log can be obtained using
MessageLogger.getInstance().getLog();
Create a new Logging class and have that class have a static constructor. Add your logging method to this class. Make the static constructor save the logging field to a private variable. Now before you call the logging method just call your static constructor with the input field you'd like to use. This will create the class, set up the input field as the destination, and now you can simply just call the log function from anywhere.
Traditionally, the way you let static methods interact with private variables is to pass them in. Pass in a pointer to your textbox.
so instead of
public static function getTimeStamp():uint { ... }
you have
public static function writeTimeStamp(messageBox):uint { ... }
The syntax might be incorrect as I'm not an AS dev but, do you see what I mean? From there, that block of code can access messageBox as if it were a local variable. Well it is.
(I renamed the method name for clarity. You could even stop it returning a variable if it doesn't need to but you'll need to change the declaration further.)
In your updated post the debug text field needs to be added to the display list somewhere. Right now it looks like it is just created and used during that log method. You add display objects to the display list by calling addChild( displayObject:DisplayObject ):Boolean; on a DisplayObjectContainer that is already a child of stage.