1

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

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

我正在寻找比MovieClip(parent.parent.parent.parent.parent).myVar(有效)更愚蠢的方法

编辑:这是一个可定制的化身,具有不同的动画。舞台上会有不止一个头像。- 与 dispatchEvents 配合得很好

谢谢!

4

2 回答 2

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)

通过控制反转 (IoC)进行的依赖注入是一种设计模式,它消除了硬编码的依赖关系,并通过在运行时与编译时绑定来实现解耦。

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

活动

事件可以冒泡,但很难再冒泡。

孩子很容易将事件冒泡到上级父级,但在通过后代子级向下传递值时通常很差。

于 2013-05-05T21:08:00.567 回答
2

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

假设您调用了一个 MovieClip container,并且您希望它的第 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;
  }

在您的 SixthChild 课程中,您只需调度一个事件来执行该通信和结果:

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

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

// in your sixthChild's class 

public var uberParent:MovieClip;

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


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

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

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

于 2013-05-05T20:55:39.343 回答