将重复项添加到现有节点时 Mx Tree 失败

Mx Tree fails when duplicate items are added to an existing node

我正在维护一个大型遗留 Flex 4.6 项目,该项目拒绝终止,并且 运行 遇到我无法解决的 Mx Tree 组件问题。要点是 将项目添加到现有节点 如果项目是重复的,则会表现出奇怪的行为。如果节点是使用唯一项创建的,则组件的行为符合预期。

例如,下图显示了将文件"AAAAA.png"多次添加到现有节点的结果。突出显示变得疯狂,组件似乎对它有多少项目感到困惑(已经测试过)。

我已经尝试了 "refresh tree" 重置数据提供者等的黑客攻击(如下),我在各种支持 Array Collections 上调用刷新。我开始尝试用某人提出的 Spark Tree 替换 Mx Tree,但时间太长了。

在我告诉客户放弃这个功能之前,有没有人想过可能是什么问题?我更像是一个 Actionscript 而不是 Flex 开发人员,除了使用它们之外,我不知道如何处理组件。


    protected function vfAddToBtn_clickHandler(event:MouseEvent):void
    {
        if (virtualFoldersList.selectedItem == null){
            Alert.show("Please select a virtual folder to add to", "Add to Virtual Folder", Alert.OK);

        } else {
            if (briefcaseData.currentSelectionsList.length > 0){
                var vf:VirtualFolder = virtualFoldersList.selectedItem as VirtualFolder;

                if (vf != null){
                    vf.children.addAll(briefcaseData.currentSelectionsList);
                    vf.children.refresh();
                    briefcaseData.virtualFoldersArray.refresh();
                    refreshTree(virtualFoldersList);

                } else {
                    trace("ERROR: vfAddToBtn_clickHandler vf is null");
                }
            }
        }
    }

        private function refreshTree(tree:Tree) : void
        {
            var selectedIndex : int = tree.selectedIndex;
            var openItems : Object = tree.openItems;
            tree.dataProvider = tree.dataProvider;
            tree.openItems = openItems;
            tree.validateNow();
            tree.selectedIndex = selectedIndex;
        } 

是briefcaseData.currentSelectionsListXML列表还是XML?

使用新的XML / XML在下行相应地列出

vf.children.addAll(briefcaseData.currentSelectionsList)

作为

vf.children.addAll(new XMLList(briefcaseData.currentSelectionsList))

答案是...Flex 4.6 中的 Mx Flex Tree 刚刚损坏。我已经尝试了所有方法,甚至从我试图合并的两个 ArrayCollections 的源数组中创建了一个新的 ArrayCollection(下面的代码)。结果是一样的:如果有重复的项目,那么组件中突出显示的翻转项目是错误的,组件会混淆它包含多少项目。

好吧。


protected function vfAddToBtn_clickHandler(event:MouseEvent):void
            {
                if (virtualFoldersList.selectedItem == null){
                    Alert.show("Please select a virtual folder to add to", "Add to Virtual Folder", Alert.OK);

                } else {
                    if (briefcaseData.currentSelectionsList.length > 0){
                        var vf:VirtualFolder = virtualFoldersList.selectedItem as VirtualFolder;

                        if (vf != null){

                            var temp: Array = new Array();
                            var sourceArray: Array;
                            var i:int;

                            if (vf.children.length > 0){
                                sourceArray = vf.children.source;
                                for (i=0; i < sourceArray.length; i++){
                                    temp.push(sourceArray[i]);
                                }
                            }

                            sourceArray = briefcaseData.currentSelectionsList.source;
                            for (i=0; i < sourceArray.length; i++){
                                temp.push(sourceArray[i]);
                            }

                            vf.children = new ArrayCollection(temp);
                            vf.children.refresh();
                            briefcaseData.virtualFoldersArray.refresh();
                            refreshTree(virtualFoldersList);

                        } else {
                            trace("ERROR: vfAddToBtn_clickHandler vf is null");
                        }
                    }
                }
            }

我已经为我之前给出的答案创建了一个示例应用程序,它对我来说运行良好。请检查此代码。

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
           xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"
            creationComplete="creationCompleteHandler(event)">
<s:layout>
    <s:VerticalLayout />
</s:layout>
<fx:Declarations>
    <fx:XML id="xmlData"><list>
        <department title="Finance" code="200">
            <employee name="John H"/>
            <employee name="Sam K"/>
        </department>
        <department title="Operations" code="400">
            <employee name="Bill C"/>
            <employee name="Jill W"/>
        </department>
        <department title="Engineering" code="300">
            <employee name="Erin M"/>
            <employee name="Ann B"/>
        </department>
    </list></fx:XML>
    <fx:XML id="empData"><employee></employee></fx:XML>
</fx:Declarations>
<fx:Script>

    import mx.collections.XMLListCollection;
    import mx.events.FlexEvent;

    [Bindable]
    private var company:XML;
    [Bindable]
    private var companyData:XMLListCollection;

    private function treeLabel(item:Object):String {
        var node:XML = XML(item);
        if (node.localName() == "department")
            return node.@title;
        else
            return node.@name;
    }

    private function addEmployee():void {
        if (tree.selectedItem.localName() == "employee")
            return;
        var newNode:XML = new XML(empData);
        newNode.@name = empName.text;
        var dept:XMLList = XMLList(tree.selectedItem);
        if (dept.length() > 0) {
            dept.appendChild(newNode);
            empName.text = "";
        }
        companyData.refresh();
    }

    private function removeEmployee():void {
        var node:XML = XML(tree.selectedItem);
        if (node == null)
            return;
        if (node.localName() != "employee")
            return;
        var children:XMLList = XMLList(node.parent()).children();
        for (var i:Number = children.length() - 1; i >= 0; i--) {
            if (children[i].@name == node.@name) {
                delete children[i];
            }
        }
    }

    private function creationCompleteHandler(event:FlexEvent):void {
        company = new XML(xmlData);
        companyData = new XMLListCollection(company.department)
    }
</fx:Script>
<mx:Tree id="tree" top="72" left="50" dataProvider="{companyData}"
         labelFunction="treeLabel" height="225" width="300"
         defaultLeafIcon="{null}" folderClosedIcon="{null}"
         folderOpenIcon="{null}"/>
<mx:VBox>
    <mx:HBox>
        <mx:Button label="Add Operations Employee" click="addEmployee();" />
        <mx:TextInput id="empName" />
    </mx:HBox>
    <mx:Button label="Remove Selected Employee" click="removeEmployee();" />
</mx:VBox>