将重复项添加到现有节点时 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>
我正在维护一个大型遗留 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>