0

次に示すように、指定された XML 要素に応じて表示オブジェクトをステージにレンダリングしています。

PageRenderer.as

private static var curElements:Dictionary = new Dictionary();

//renders the current page
        private static function renderCode(pageCode:XML):void
        {

            if (pageCode)
            {
                //loop all elements from top to bottom
                for each (var child:XML in pageCode.descendants())
                {
                    var render:DisplayObject = ElementRenderer.render(child);
                    if (render)
                    {
                        WebBuilder.mainDisplay.addChild(render);
                        curElements[child] = render;    
                    }
                }   
            }
        }

したがって、各 XML 要素には、関連付けられたレンダリングされた形状があります。XML 要素がある場合は、次のように形状にアクセスできます。 var shape:DisplayObject = curElements[xmlElement];

これは、同じクラス内で正常に機能します。

ただし、今では、形状の選択を処理し、形状で行われたアクションを xml 要素に反映する ElementSelector クラスもあります。これを行うには、形状がクリックされたときに XML 要素を取得する必要があります。

ElementSelector.as

private static var currentSelection:XML;    

//fired when the stage has been clicked
            private static function stageClicked(event:MouseEvent):void
            {
                //if the element selector has been enabled
                if (enabled)
                {
                    var allPages:Array = CodeHandler.getPageCodes();
                    var mainElement:XML = allPages[CodeHandler.getCurPageId()];
                    var targetElement:XML = CodeHandler.getDeepestElementAtPos(mainElement, 0, event.stageX, event.stageY)["xml"];
                    if ((targetElement.localName() != "page") && (targetElement != currentSelection))
                    { //we have a new element selected
                        Utils.log("ElementSelector now selecting: " + targetElement.localName());
                        select(targetElement);
                    }
                    else if ((targetElement.localName() == "page") && (currentSelection))
                    { //the selection has been lost
                        Utils.log("ElementSelector now dropping selection.");
                        deselect();
                    }
                }
            }

            //sets the new selection
            private static function select(element:XML):void
            {
                if (currentSelection) deselect();
                currentSelection = element;

                var curElements:Dictionary = PageRenderer.getElements();
                var render:DisplayObject = curElements[element];
                trace(render);
            }

    //drops the current selection
            private static function deselect():void
            {
                currentSelection = null;
            }

StageClicked イベント関数のみを追加したので、私の手順がどのように機能するかがわかります。その機能自体は正常に動作します。問題は select() メソッド内にあるようです。

ここで奇妙なことに、curElements[element] は undefined を返し、render は null を返します。

私はこのようにデバッグしようとしました(selectメソッドの一番下):

for (var key:Object in curElements) 
                {
                    if (key === element)
                    {
                        trace("key === element");
                    }
                                trace(curElements[key] === curElements[element]);
                    trace(curElements[key]);
                    trace(curElements[element]);
                }

戻り値:

key === element
false
[object Shape]
undefined

なぜこうなった?a === b なら、dic[a] === dic[b] ですね。まあ、どうやらそうではありません。

それで、キーは本当にそこにあります...そして、それは設定されたキーと同じです。

連想表示オブジェクトを返さないのはなぜですか?

4

2 に答える 2

2

これが役に立たない場合は申し訳ありませんが、XML オブジェクトを辞書キーとして使用してアプリケーションを構築した方法には、そもそも欠陥があると思います。キーに使用される XML に id 属性を含めるなど、要素にインデックスを付ける別の方法を用意することを強くお勧めします。または、インクリメントされた整数インデックスを使用することもできます。

もう 1 つのオプションは、ElementRenderer.render() によって返されるオブジェクトのクラス (またはインターフェイス) を作成し、そのインターフェイスのプロパティとして ID を持つことです。

public interface IRenderedElement
{
  function get id() : String;
}

次に、要素をフラット配列またはベクターに格納できます。

XML ノードを使用している理由が、XML で宣言されたデータを格納する必要があるためである場合は、XML を解析し、弱く型付けされた要素内ではなく、カスタム Element クラスにデータを格納することを強くお勧めします。 、動的 XML オブジェクト。上記のインターフェイスは、そのようなデータのプロパティを配置するのに適しています。

クリックされた要素を見つけるだけでよい場合は、すべての要素にイベント リスナーを追加し、Event.currentTargetプロパティを使用して要素を識別することをお勧めします。

var element:DisplayObject = ElementRenderer.render(child);
render.addEventListener(MouseEvent.CLICK, handleElementClick);

/* ... */

function handleElementClick(ev : MouseEvent) : void
{
  var element : IRenderedElement = ev.currentTarget as IRenderedElement;

  // do something here
}

また、単純にすべての要素の親、つまりWebBuilder.mainDisplayをリッスンし、 Event.targetプロパティを使用して、クリックされた正確なオブジェクトを見つけることもできます。

于 2010-01-01T12:27:22.970 に答える
0

ディクショナリは、非プリミティブ オブジェクト キーのキー比較に厳密等価 (===) を使用します。したがってkey == elements、truekey === elemetsを返す可能性がありますが、あなたの場合は false を返します。要素とキーオブジェクトが異なるため。
Dictionary の代わりに連想配列を使用してみてください。

于 2009-12-28T12:48:04.267 に答える