2011-06-03 12 views
5

tengo una clase que por el momento es bastante desordenado/repetitivo:La creación de múltiples propiedades de sólo lectura de forma dinámica en AS3

public class AvFramework extends Object 
{ 
    // vars 
    private var _handler:AvHandler; 
    private var _keyboard:AvKeyboard; 
    private var _manager:AvManager; 

    /** 
    * Constructor 
    */ 
    public function AvFramework() 
    { 
     _handler = new AvHandler(); 
     _keyboard = new AvKeyboard(); 
     _manager = new AvManager(); 

     // attach 
     _handler.framework = this; 
     _keyboard.framework = this; 
     _manager.framework = this; 
    } 

    /** 
    * Getters 
    */ 
    public function get keyboard():AvKeyboard{ return _keyboard; } 
    public function get manager():AvManager{ return _manager; } 
} 

Esta clase sólo va a tener que hacer uso de más y más clases, y Realmente no quiero tener 3 listas enormes para esto como el anterior.

¿Hay alguna manera de hacer lo anterior de forma dinámica? Tal vez usando getDefinitonByName() en un bucle de cadenas para representar las clases que quiero crear.

También quiero que las propiedades sean de solo lectura y que se pueda acceder a través del framework.myDynamicVarHere.

Estoy pensando en algo como lo siguiente:

  1. creo una lista de las clases que quiero crear instancias de pares, con el nombre de la variable que debe tener acceso a.
  2. necesitaré para hacer la clase dynamic para que pueda establecer los VARs través this["var"] = new Blah();

fragmento rápida de donde van mis pensamientos:

var required:Object = 
{ 
    keyboard: "avian.framework.background.AvKeyboard", 
    manager: "avian.framework.background.AvManager", 
    handler: "avian.framework.background.AvHandler" 
}; 

var i:String; 
for(i in required) 
{ 
    var Req:Class = Class(getDefinitionByName(required[i])); 

    this[i] = new Req(); 
    AvFrameworkObject(this[i]).framework = this; 
} 

simplemente no está seguro de cómo iba a ser capaz de para hacer estos de solo lectura.

+0

nice question !!! – Eugeny89

+0

esto: 'var i: String; for (i en required)' no es necesario. Con 'for (var i: String in required)' solo inicializa la cadena una vez y la cadena persiste después del ciclo for. Lo único que obtiene la línea adicional es ... una línea adicional. – cwallenpoole

+0

@cwallenpoole Cierto, esto simplemente me parece más agradable. @ Eugeny89 Gracias :) – Marty

Respuesta

4

Puede usar la clase Proxy para controlar la llamada a obtener/configurar y completar la respuesta de Eugeny89. Mira http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Proxy.html o http://blog.joa-ebert.com/2007/05/25/as3-proxy-example/

var required:Object = 
{ 
    keyboard: "avian.framework.background.AvKeyboard", 
    manager: "avian.framework.background.AvManager", 
    handler: "avian.framework.background.AvHandler" 
}; 
... 

import flash.utils.Proxy; 
import flash.utils.flash_proxy; 
public dynamic class AvFramework extends Proxy { 
    private var holder: Object = {}; 

    public function AvFramework() { 
     var i:String; 
     for(i in required) 
     { 
      var Req:Class = Class(getDefinitionByName(required[i])); 
      var name = //get Class name from required[i] e.g. AvKeyboard from avian.framework.background.AvKeyboard 
      holder[name] = new Req(); 
      holder[name].framework = this; 
     } 
    } 

    flash_proxy override function getProperty(name: *): * 
    { 
     return holder[name]; 
    } 

    flash_proxy function setProperty(name:*, value:*):void 
    { 
     // Do nothing 
    } 
} 

Con este código, cuando se hace myAvFrameworkObj.something, getProperty() se llama de forma automática y se obtiene el nombre de propiedad de "nombre" variable.

+0

Debes tener private var holder: Object = {}; (y no lo inicializa nuevo Object en el constructor) si quiere seguir los estándares estilísticos de Adobe. – cwallenpoole

+0

¡Por qué no, gracias! –

+0

¡excelente respuesta! Putting +1! – Eugeny89

1

Tal vez intenta envolver esa larga lista de classws en objeto:

var required:Object = 
{ 
    keyboard: "avian.framework.background.AvKeyboard", 
    manager: "avian.framework.background.AvManager", 
    handler: "avian.framework.background.AvHandler" 
}; 
... 

public class AvFramework extends Object { 
    private var holder: Object; 

    public function AvFramework() { 
     holder = new Object(); 

     var i:String; 
     for(i in required) 
     { 
      var Req:Class = Class(getDefinitionByName(required[i])); 
      var name = //get Class name from required[i] e.g. AvKeyboard from avian.framework.background.AvKeyboard 
      holder[name] = new Req(); 
      holder[name].framework = this; 
     } 
    } 

    public var getHolder() { return holder; } 
} 

Se puede hacer referencia a, por ejemplo, AvKeyboard por framework.getHolder()["AvKeyboard"] o incluso por framework.getHolder()[someVar]. Entonces, todas estas clases de required son de solo lectura, ya que holder es de solo lectura.

Espero que te ayuden!

+0

Buena respuesta - He tenido el mismo pensamiento, sin embargo acceder a todo (desde un objeto de framework) a través de framework.getHolder() ["cosas"] sobre framework.things es extremadamente desagradable :( – Marty

Cuestiones relacionadas