AS3:如何进入孩子的孩子儿童?(AS3: How to access children of ch

2019-09-28 15:39发布

有没有更好的(更快,更短或更整洁)的方式来访问子精灵(物体)3层以上的深? 如果孩子们都被赋予的名字,你知道的名字。 有没有更好的办法做到这一点比我下面提出的代码?

VAR mySprite上:级DisplayObjectContainer = layerASprite.getChildByName( “ 层1.”)如DisplayObjectContainer;

mySprite上= mySprite.getChildByName( “layerB”)如DisplayObjectContainer;

mySprite.getChildByName( “layerC”).Y = 200;

Answer 1:

如果它们是唯一的,你可以创建静态类变​​量/方法形式的“全球性”的注册表:

package
{
    public class Registry
    {
        static private var hash:Object = new Object;

        static public function register(name:String, target:DisplayObject):void
        {
            hash[name] = target;
        }

        static public function access(name:String):DisplayObject
        {
            return hash[name];
        }
    }
}

用法:

// Any MovieClip, frame 1 or class constructor.
import Registry;

Registry.register("deepChild", this);

// From any other place.
import Registry;

Registry.access("deepChild").y = 200;

或者您可以使用由单一字符串参数挖掘孩子的孩子的方法:

function offSpring(path:String):DisplayObject
{
    var aSplit:Array = path.split(".");
    var result:DisplayObject = this;

    while (aSplit.length)
    {
        var aParent:DisplayObjectContainer = result as DisplayObjectContainer;

        if (!aParent) return null;

        result = aParent.getChildByName(aSplit.shift());
    }

    return result;
}

用法:

offSpring("layerA.layerB.layerC").y = 200;


Answer 2:

由于我不是静态属性的超级粉丝,所以我也提议递归搜索:

public function findChild(d:DisplayObject, n:String):DisplayObject {
    var dc:DisplayObjectContainer = d as DisplayObjectContainer; if (!dc) return null;
    for (var i:int = 0; i < dc.numChildren; i++){
        var ch:DisplayObject = dc.getChildAt(i);
        if (ch.name == n || (ch = findChild(ch, n))) return ch;
    }return null;
}

比你可以简单地输入:

 var d:DisplayObject = findChild(stage, "childName");

找到与第一个孩子childName名字在舞台上的任何地方。

我只是写它,测试它一次,但我希望它的罚款。

优点

  • 你不需要做任何额外的步骤,用这种方法来工作。 你甚至都不需要命名你寻找孩子的容器。
  • 您可以在开始任何搜索DisplayObjectContainer你想要的。
  • 如果你决定在某些时候,你需要你需要你的子窗体容器移动A集装箱B ,如果它仍然是同一个分支的一部分,并具有独特的名称,因此需要在代码中没有变化。

缺点

  • 这可能是昂贵的,特别是如果你有广泛的分行。
  • 你需要让你的孩子肯定名称在搜索分公司唯一的。

更复杂的版本

作为搜索孩子们通常是定容器的直接子或者是在比较接近的水平你可能寻找孩子一个水平时,虽然它是有点棘手。 例如我的alpha版本:

/**
 * Perform parallel/sprial recursive search in this container to find child with given name.
 * This means that this function will first check names of all child of this container and and then go to deeper level.
 * In other words, no element will be tested on level x+1 if not all elements were tested on level x.
 * This is true for all levels until whole tree is exhausted. This method is using token argument for such functionallity.
 * @param   n name of child element to be found.
 * @param   t token passed internally for sipral search. You should not specify this if you want the function to search a whole tree.
 * The token has only single value which is basically a desired level at which child should be searched for.
 * Level 1 means this function will only check its own childrens, level 2 means that only childs of childs of this container will be checked and so one.
 * However note that if you specify a token with some level, only that single level will be searched.
 * On the other hand if given token is null, this will check childs on level 1, then level 2, 3... and it will countinue until deepest level has been reached. 
 * @return nearest child with specified name or null if no child with given name found.
 */
public function findChild(n:String, t:SearchToken = null, ind:String = ""):SGLElement {
    ind += "    ";
    var r:Boolean = (t) ? false : true; //is this call root of search.
    t = (t) ? t.offL( -1) : new SearchToken(0); //create new token if not given or decrement current token value. 
    //trace(ind + "F", this.name, ":", t);
    //if (!t) t = new SearchToken(0);
    //--t.l;
    var cl:SearchToken = new SearchToken(t.l); //current search level.
    var exc:int = 0; //exhausted childrens.
    if(t.l == 0){//search own children
        for (var i:int = 0; i < _childs.length; i++) { //trace(ind + "  c", _childs[i].name);
            if (_childs[i].name == n) return _childs[i]; }
        if (r) ++cl.l; else return null;
    }
    while( cl.l > 0){
        if (exc >= _childs.length) { t.l = -1; return null;}
        for (i = 0; i < _childs.length; i++) {
            //trace(ind + "ch", t,":", i, _childs[i].name, _childs[i]);
            if (!(_childs[i] as SGLElementContainer)) continue;
            //trace(ind + "t", t, i);
            t.l = cl.l;
            var e:SGLElement = SGLElementContainer(_childs[i]).findChild(n, t, ind);
            //++cl.l;
            if (e) return e;
            else if (t.l < 0) exc++;
        }
        //trace(ind + "END_LEVEL>>>>", t);
        if (!r) return null;
        //t.l = cl.l; 
        ++cl.l;
    }
    return null;
}

令牌类

package adnss.common.utils 
{
    public class SearchToken 
    {
        /**Current level**/
        public var l:int;

        public function SearchToken(levelValue:int) {l = levelValue;}

        public function toString():String {return String(l);}

        /**Set level value and return this token instance.**/
        public function setL(v:int):SearchToken { l = v; return this; }

        /**Add given offset value to level value and return this token instance.**/
        public function offL(v:int):SearchToken { l += v; return this;} 
    }

}

我注意到,我不知道是什么,所以我给我自己的名字命名的技术对于这样的搜索,而不是使用这种方法用于显示列表,所以你需要去适应它。 这一点很难解释这一点,但如果你有一些问题,它随时问。



文章来源: AS3: How to access children of children of children?