簡體   English   中英

AS3 / Flex 4:尋找嵌套兒童的最實用方法

[英]AS3/Flex 4: Most Practical Way To Find Nested Children

我有點想要一些Flex / AIR的東西。 我有一個非常扎實的AS3背景,但鑒於Flex固有的層次結構復雜性(與常規Flash相比),我遇到了一個問題。

讓我們假設你有一個應用程序,其中幾乎所有東西都是事件驅動的(常見的)。 訪問事件目標附近的元素或事件目標本身是微不足道的。 然而,我試圖找到最實用的(閱讀:最好,最有效)的方法來找到遠離當前環境的孩子。

我知道有像getChildAt()getChildByName()這樣的函數,但它假定父上下文; 如果您正在尋找的元素(Flex)是幾個父母,在一個兄弟姐妹,然后幾個孩子下來怎么辦? 我們理所當然地認為像jQuery這樣容易做到這一點,但顯然我們在AS3中沒有那么奢侈。

以下任何一項有效嗎? 有沒有更好的辦法?

  1. 通過父母和父母的父母進行迭代,直到找到一個停止點,找到兄弟姐妹,並重復孩子和他們的孩子直到找到目標;

  2. 將關鍵對象保存在全局對象庫(sic)中並根據需要引用它們(yech)

  3. 使用特定的點符號到達目標,包括元素(如皮膚及其容器 - 再次出現)

任何想法將不勝感激。

編輯:

為了澄清,讓我們來看一個空的Flex 4 AIR應用程序。 我們將WindowedApplication作為根,顯然,讓我們分別添加兩個具有ID navContainermainContainer SkinnableContainernavContainer 兩者都有自定義皮膚。 mainContainer ,我們有另一個具有垂直布局和ID mainContent SkinnableContainer ,並且作為它的一個子mainContent ,它有一個對象(任何可以做的 - 可能是一個BorderContainer ),例如ID animatedBox navContainer ,我們有一個spark Button ,它有一個綁定MouseEvent.CLICK的監聽MouseEvent.CLICK 在該函數中,我們將要訪問animatedBoxnativeWindow.mainContainer.mainContent.animatedBox )並對其進行動畫處理以更改,例如,它的寬度。

目標是以盡可能不引人注目和高效的方式訪問遠程DisplayObjectanimatedBox ),同時仍然符合我明顯尚未擁有的Flex標准。 :)

在我的實現中很容易做到(但它在純AS3中):

在處理點擊的顯示對象中:

private function onClick(e:MouseEvent):void{
    Radio.broadcast(new CustomEvent(id, ..params));
}

在動畫框中:

Radio.addListener(id, new Reciever(uid, animate));

private function animate(e:CustomEvent) {
   //needed code and access of CustomEvent props you pass
}

UPD:

package lazylib.broadcast 
{
    /**
     * ...
     * @author www0z0k
     */
    public class Reciever 
    {
        private var id: String;
        private var toRun: Function;
        /*@param nm - unique listener id - required
         *@param fn - event handler function - required*/
        public function Reciever(nm:String, fn:Function) 
        {
            id = nm;
            toRun = fn;         
        }

        public function onEvent(e:* = null):String {
            if (e == null) { return id; }
            toRun(e);
            return id;
        }

        public function get ID():String { return id; }

    }

}

package lazylib.broadcast
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    /**
     * ...
     * @author www0z0k
     */
    public final class Radio extends EventDispatcher
    {
        private static var listeners: Object = new Object();
        private static var archive: Array = new Array();
        private static var forSlowpokes: Object = new Object();

        public static function get ForSlowpokes():Object { return forSlowpokes; }

        public static function addListener(type: String , listener: Reciever):Boolean {
            listeners['anchor'] = null;
            if (!listeners[type]) { 
                var o: Object = new Object();
                listeners[type] = o;
            }
            if (!listeners[type][listener.ID]) {
                listeners[type][listener.ID] = listener; 
                return true;
            }else {
                return false;
            }
        }

        public static function broadcast(evt: * , singleUse:Boolean = false):void {
            var type:String = (evt as Event).type;          
            if (listeners[type]) {
                var returned: Array = new Array();
                for (var i: String in listeners[type]) {
                    if(listeners[type][i]){
                        var fnRetVal: String = listeners[type][i].onEvent(evt);
                        returned.push(fnRetVal);
                    }else{
                        //trace("no listener for id = " + i + ' , type = ' + type);
                    }
                }

            }else {
                //trace("nobody's interested in : \"" + type + "\"");
            }
            if (singleUse) {
                forSlowpokes[type] = 'you missed it realtime';
                delete listeners[type];
            }
        }

        public static function clearDeadFuncs(namez:Object):void {
            for (var a:String in namez) {
                if (a != 'anchor') {
                    killListener(a, namez[a]);
                }
            }
        }

        public static function killListener(type: String , id: String):Boolean {
            if (!listeners[type]) { 
                //trace("there are no listeners for event : " + "\"" + type + "\"");
                return false;
            }else {
                if (!listeners[type][id]) {
                    //trace("there is no \"" + id + "\" listener for event : " + "\"" + type + "\"");
                    return false;
                }else {
                    listeners[type][id] = null;
                    //trace("removed listener \"" + id + "\" for event : " + "\"" + type + "\"");
                    var evt2kill: Number = 0;
                    for (var str: String in listeners[type]) {
                        if (listeners[type][str]) {
                            evt2kill++;
                        }
                    }
                    if (evt2kill == 0) {
                        delete listeners[type];
                        //trace("no more listeners for event : " + "\"" + type + "\"");
                        return true;
                    }
                    return true;
                }
            }
        }
    }
}

按原樣交付;)

我們理所當然地認為像jQuery這樣容易做到這一點,但顯然我們在AS3中沒有那么奢侈。

好吧有這個: http//tech.nitoyon.com/blog/2008/01/as3query_alpha.html

我也問了很多次這個問題。 還沒有找到問題的最終解決方案。 通過父母和父母進行迭代絕對是一種方式,但必須謹慎對待,因為在運行時期間應用程序中的關系可能會發生變化。 幾天前我寫了一個簡單的方法 ,讓你遍歷給定對象的所有父級。 絕對不是一個優雅的解決方案,但它到目前為止工作。 SWIZ框架還提供了很好的方法,通過代碼注入和事件中介來促進對象之間的通信。 也許值得一看......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM