0

我正在根据给定的 XML 元素将显示对象渲染到舞台,如您在此处看到的:

页面渲染器.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];

这在同一个班级中工作正常。

但是,现在我还有 ElementSelector 类,它处理形状的选择并将对形状所做的操作反映到 xml 元素。为此,需要在单击形状时获取 XML 元素:

元素选择器.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。

我试图像这样调试它(在选择方法的底部):

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 属性。或者您可以简单地使用递增的整数索引。

另一种选择是为 ElementRenderer.render() 返回的对象创建一个类(或接口),并将您的 ID 作为该接口中的属性:

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

然后,您可以将元素存储在平面数组或 Vector 中。

如果您使用 XML 节点的原因是您需要存储在 XML 中声明的数据,那么我强烈建议您解析 XML 并将数据存储在自定义元素类中,而不是在弱类型中, 动态 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可能会返回 true,但key === elemets在您的情况下会返回 false。由于元素和关键对象不同。
尝试使用关联数组而不是字典。

于 2009-12-28T12:48:04.267 回答