[英]AS3/Flex 4: Most Practical Way To Find Nested Children
我有點想要一些Flex / AIR的東西。 我有一個非常扎實的AS3背景,但鑒於Flex固有的層次結構復雜性(與常規Flash相比),我遇到了一個問題。
讓我們假設你有一個應用程序,其中幾乎所有東西都是事件驅動的(常見的)。 訪問事件目標附近的元素或事件目標本身是微不足道的。 然而,我試圖找到最實用的(閱讀:最好,最有效)的方法來找到遠離當前環境的孩子。
我知道有像getChildAt()
和getChildByName()
這樣的函數,但它假定父上下文; 如果您正在尋找的元素(Flex)是幾個父母,在一個兄弟姐妹,然后幾個孩子下來怎么辦? 我們理所當然地認為像jQuery這樣容易做到這一點,但顯然我們在AS3中沒有那么奢侈。
以下任何一項有效嗎? 有沒有更好的辦法?
通過父母和父母的父母進行迭代,直到找到一個停止點,找到兄弟姐妹,並重復孩子和他們的孩子直到找到目標;
將關鍵對象保存在全局對象庫(sic)中並根據需要引用它們(yech)
使用特定的點符號到達目標,包括元素(如皮膚及其容器 - 再次出現)
任何想法將不勝感激。
編輯:
為了澄清,讓我們來看一個空的Flex 4 AIR應用程序。 我們將WindowedApplication
作為根,顯然,讓我們分別添加兩個具有ID navContainer
和mainContainer
SkinnableContainer
子navContainer
。 兩者都有自定義皮膚。 在mainContainer
,我們有另一個具有垂直布局和ID mainContent
SkinnableContainer
,並且作為它的一個子mainContent
,它有一個對象(任何可以做的 - 可能是一個BorderContainer
),例如ID animatedBox
。 在navContainer
,我們有一個spark Button
,它有一個綁定MouseEvent.CLICK
的監聽MouseEvent.CLICK
。 在該函數中,我們將要訪問animatedBox
( nativeWindow.mainContainer.mainContent.animatedBox
)並對其進行動畫處理以更改,例如,它的寬度。
目標是以盡可能不引人注目和高效的方式訪問遠程DisplayObject
( animatedBox
),同時仍然符合我明顯尚未擁有的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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.