AS3/Flex 4:查找嵌套子项的最实用方法 [英] AS3/Flex 4: Most Practical Way To Find Nested Children

查看:22
本文介绍了AS3/Flex 4:查找嵌套子项的最实用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点想一头扎进一些 Flex/AIR 的东西.我对 AS3 有相当扎实的背景,但考虑到 Flex 固有的层次结构复杂性(与常规 Flash 相比),我遇到了一个问题.

I'm sort of jumping in headfirst to some Flex/AIR stuff. I have a pretty solid background with AS3, but given the inherent hierarchal complexity of Flex (compared to regular Flash), I'm running into an issue.

让我们假设您有一个应用程序,其中几乎所有内容都是事件驱动的(常见的).访问事件目标附近的元素或事件目标本身是微不足道的.然而,我试图找到最实用(读作:最好、最有效)的方法来找到远离当前上下文的孩子.

Let's assume that you have an app where pretty much everything is event driven (common). Accessing elements in the near vicinity of the event target, or the event target itself, is trivial. I'm trying to find, however, the most practical (read: best, most efficient) way to find children that are far removed from the current context.

我知道有诸如 getChildAt()getChildByName() 之类的函数,但它假定父上下文;如果您要查找的元素 (Flex) 是多个父元素,在一个兄弟元素中,然后是多个子元素,该怎么办?我们认为 jQuery 之类的东西很容易做到这一点是理所当然的,但显然我们在 AS3 中没有那么奢侈.

I know there are functions like getChildAt() and getChildByName(), but that assumes a parent context; what if the element (Flex) you're looking for is several parents up, in a sibling, and then several children down? We take for granted things like jQuery that do this easily, but obviously we don't have that luxury in AS3.

以下是否有效?有没有更好的办法?

Are any of the following valid? Is there a better way?

  1. 遍历父母和父母的父母,直到找到停止点,找到兄弟姐妹,然后遍历孩子和他们的孩子,直到找到目标;

  1. Iterate through parents and parents' parents until you find a stop point, find the sibling, and iterate through children and their children until you find your target;

将关键对象保存在全局对象存储 (sic) 中并在必要时引用它们 (yech)

Keep key objects in a global object store (sic) and reference them as necessary (yech)

使用特定的点符号来达到目标​​,包括元素(如皮肤及其容器 - 再次是)

Use specific dot notation to reach the target, including elements (like skins and their containers - yech again)

如有任何想法,我们将不胜感激.

Any thoughts would be appreciated.

为了澄清,让我们以一个空的 Flex 4 AIR 应用程序为例.显然,我们将 WindowedApplication 作为根,让我们添加两个 SkinnableContainer 孩子,ID 分别为 navContainermainContainer.两者都有自定义皮肤.在 mainContainer 中,我们有另一个具有垂直布局和 ID mainContentSkinnableContainer,作为它的一个孩子,它有一个对象(任何将do - 例如,一个带有 ID animatedBox 的火花 BorderContainer,也许).在 navContainer 中,我们有一个 spark Button,它有一个绑定 MouseEvent.CLICK 的侦听器.在该函数中,我们将要访问 animatedBox (nativeWindow.mainContainer.mainContent.animatedBox) 并为其设置动画以更改其宽度.

To clarify, let's take an empty Flex 4 AIR app. We have WindowedApplication as the root, obviously, and let's add two SkinnableContainer children with IDs navContainer and mainContainer, respectively. Both have custom skins. Within mainContainer, we have another SkinnableContainer with a vertical layout and ID mainContent, and as one of its children, it has an object (any will do - a spark BorderContainer, maybe) with the ID animatedBox, for example. Within the navContainer, we have a spark Button, which has a listener bound for MouseEvent.CLICK. Within that function, we are going to want to access animatedBox (nativeWindow.mainContainer.mainContent.animatedBox) and animate it to change, say, it's width.

目标是以尽可能不引人注目和高效的方式访问远处的 DisplayObject (animatedBox),同时仍然符合我明确拥有的 Flex 标准尚未拥有.:)

The goal is to access that distant DisplayObject (animatedBox) in a way that is as unobtrusive and efficient as possible, while still conforming to Flex standards that I clearly have yet to possess. :)

推荐答案

在我的实现中很容易做到(但它是在纯 AS3 中):

in my implementation it is easy to do (however it's in pure AS3):

在处理点击的显示对象中:

in display object which handles the click:

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
}

更新:

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;
                }
            }
        }
    }
}

按原样交付;)

这篇关于AS3/Flex 4:查找嵌套子项的最实用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆