如何从深层嵌套子中访问类变量

时间:2013-05-05 20:07:25

标签: actionscript-3 actionscript

如何访问深层嵌套子级中的类变量?

场景:具有公共变量myVar的类,我想从第六个孩子访问它。

我正在寻找比MovieClip(parent.parent.parent.parent.parent).myVar(有效)

更少的愚蠢方式

编辑:这是一个可自定义的头像,具有不同的动画。舞台上将有不止一个头像。 - 适用于dispatchEvents

谢谢!

2 个答案:

答案 0 :(得分:3)

通常这种类型的紧耦合代表了更大的设计模式问题。

静态方法

如果只有一个上升的父类,例如一个总体游戏实例,你可以访问一个静态变量。

包含myVar实例的游戏类:

package
{
    public class Game
    {
        public static var myVar:String;
    }
}

然后,任何类都可以通过以下方式访问变量:

Game.myVar

单身方法

同样,如果只有一个上升的父类,则可以实现单例类:

package
{
    public class Game
    {
        /** Data model */
        public var myVar:String;

        /** Singleton instance */
        private static var _instance:Game = new Game();

        /** Return singleton instance */
        public static function getInstance():Game
        {
            return _instance;
        }

        /** Constructor as singleton enforcer */
        public function Game()
        {
            if (_instance)
                throw new Error("Game is a singleton and can only be accessed through Game.getInstance()");
        }
    }
}

获取单例类的实例以访问变量:

var game:Game = Game.getInstance();
game.myVar;

在集合中设置

使用静态和单例方法,您可以在字典中映射实例。

例如,假设您有多个上升的父类。每个实例都可以映射到集合中,可能在应用程序模型类中:

// collection, referencing parent instance
public var map:Dictionary = new Dictionary();

// myVar variable from different parent instances:
map[parent1] = myVar;
map[parent2] = myVar;

封装

如果真正需要将模型传递给子模型,则可以封装功能以将变量传递下去。

在此示例中,父级通过在设置其自己的myVar属性时设置子级myVar变量来维护对子级的控制:

package
{
    public class Game
    {

        private var _myVar:String;

        public function get myVar():String
        {
            return _myVar;
        }

        public function set myVar(value:String):void
        {
            _myVar = value;
            child.myVar = value;
        }

    }
}

这样,当上升父类设置变量时,它会将值复制到子模型。

这对于演示模型很有意义,例如模型支持控件和UI组件;但是,我通常不建议这样做。

控制反转(IoC)

Dependency injectioninversion of control (IoC)是一种设计模式,它可以删除硬编码的依赖关系,并通过在运行时与编译时绑定来实现解耦。

有一些框架可以将此功能引入ActionScript,实现[Inject]元数据标记。

活动

事件可能会冒泡,但很难回落。

孩子很容易将一个事件冒泡到一个上升的父母身上,但是当通过后代孩子将一个值传递回来时通常很差。

答案 1 :(得分:2)

一种方法是事件系统,因为它可以让你避免这种头痛。

假设您有一个名为container的MovieClip,并且您希望它的第6个孩子能够与之通信。

只需向您的容器添加一个事件监听器,如下所示:

addEventListener("HelloItsMeTheSixthChild", sixthChildHandler);

function sixthChildHandler(e:Event):void
{
   var sixthChild:MovieClip = e.target as MovieClip;

   // now do whatever you want with that sixthChild
   // maybe call a method of sixthChild that utilizes this instance ?
   sixthChild.doStuff(this);

}

  // in your sixthChild's class
  function doStuff(uberParent:MovieClip):void
  {
       uberParent.scaleX = 5;
       uberParent.scaleY = 6;
  }

在你的第六届儿童班上,你只需派遣一个活动来执行这种沟通和结果:

dispatchEvent(new Event("HelloItsMeTheSixthChild", true));

如果您要经常使用这个远亲,您也可以将引用传递给第六个孩子并将其存储在类变量中:

// in your sixthChild's class 

public var uberParent:MovieClip;

function setUberParent(uParent:MovieClip):void
{
    uberParent = uParent;
}


function doStuffWithMyUberParent():void
{
    uberParent.rotation = 90;
}

所以只有几种与远房亲戚沟通的方式。但是,我认为确实有更好的方法来设计您的应用程序,这样您就不必再考虑这样的事情了。

例如,我不认为你的第六个孩子对那个uberParent做某事是个好主意。我认为它应该只是通过事件进行通信,让父母对这些事件作出反应。这样,如果我查看uberParent的代码,我对发生的事情非常了解,并且没有这个流氓的孩子可以随心所欲地改变它的属性。