从数据绑定数组中删除项目

时间:2009-03-26 17:35:41

标签: javascript arrays actionscript

如何从数据绑定数组中删除项?我的代码如下。

for(var i = 0; i < listBox.selectedIndices.length; i++) {
  var toRemove = listFiles.selectedIndices[i];
  dataArray.splice(toRemove, 1);
}

提前致谢!

编辑这是我的瑞士法郎。除非删除项目,否则“添加照片”将起作用。 http://www.3rdshooter.com/Content/Flash/PhotoUploader.html

  1. 添加3张不同的照片。
  2. 删除第二张照片。
  3. 添加其他照片。
  4. SWF将第二张照片添加到最后。
  5. 关于它为什么会这样做的任何想法?

    编辑2 这是我的代码

    private function OnSelectFileRefList(e:Event):void
    {
        Alert.show('addstart:' + arrayQueue.length);
        for each (var f:FileReference in fileRefList.fileList)
        {
             var lid:ListItemData = new ListItemData();
             lid.fileRef = f;
             arrayQueue[arrayQueue.length]=lid;
        }
        Alert.show('addcomplete:' + arrayQueue.length);
        listFiles.executeBindings();
        Alert.show(ListItemData(arrayQueue[arrayQueue.length-1]).fileRef.name);
        PushStatus('Added ' + fileRefList.fileList.length.toString() + ' photo(s) to queue!');
        fileRefList.fileList.length = 0;
        buttonUpload.enabled = (arrayQueue.length > 0);
    }
    
    private function OnButtonRemoveClicked(e:Event):void
    {
        for(var i:Number = 0; i < listFiles.selectedIndices.length; i++) {
            var toRemove:Number = listFiles.selectedIndices[i];
            //Alert.show(toRemove.toString());
            arrayQueue.splice(toRemove, 1);
        }
        listFiles.executeBindings();
        Alert.show('removecomplete:' + arrayQueue.length);
        PushStatus('Removed photos from queue.');
        buttonRemove.enabled = (listFiles.selectedItems.length > 0);
        buttonUpload.enabled = (arrayQueue.length > 0);
    }
    

5 个答案:

答案 0 :(得分:2)

了解两件事肯定会有所帮助:

  1. 您定位的是哪个版本的ActionScript?

  2. 根据应用程序的行为判断,当用户从要上载的文件列表中删除项目时,不会发生错误。当用户将新项添加到列表时,看起来更像是您的逻辑问题。您是否有机会发布该代码?

  3. <强>更新

    而不是:arrayQueue[arrayQueue.length]=lid

    尝试:arrayQueue.push(lid)

    这将在数组的末尾添加一个新项目,并将该项目推送到该位置。

    更新2

    好的,做了一点挖掘。事实证明,每次打开对话框时都不会清除fileList(如果每次用户选择新文件时都没有创建FileReferenceList的新实例)。将每个文件添加到数组后,需要在fileList上调用splice()。

    在AddFile()方法中尝试这样的事情......

    for(var j:int=0; j < fileRefList.fileList.length; j++)
    {
         arrayQueue.push(fileRefList.fileList[j]);
         fileRefList.fileList.splice(j, 1);
    }
    

    这将使fileList保持最新状态,而不是保留以前的选择。

答案 1 :(得分:0)

我看到一个问题。一旦拼接出数组中的第一个元素,选定的索引就不再有效。但是,这应该只是一次删除多个项目时的问题。

我认为我们需要查看更多有关您如何处理上传的代码,然后才能弄清楚发生了什么。在我看来,你正在对已删除的FileReference或其他东西进行引用。上传新文件时,而不是删除所选文件时,会出现上述问题。

答案 2 :(得分:0)

您的意思是使用listBoxlistFiles来引用相同的内容吗?

我在这里踩到了一条腿,因为我没有大量的JavaScript经验,但我的做法与我在C,C ++或Java中的做法相同:将剩余的数组元素复制到新的位置。

假设listFiles.selectedIndices已排序(并且其内容是dataArray的有效索引),代码将类似于以下内容:

(警告:未经测试的代码如下。)

// Don't bother copying any elements below the first selected element.
var writeIndex = listFiles.selectedIndices[0];
var readIndex = listFiles.selectedIndices[0] + 1;
var selectionIndex = 1;
while(writeIndex < (dataArray.length - listFiles.selectedIndices.length)) {
  if (selectionIndex < listFiles.selectedIndices.length) {
    // If the read pointer is currently at a selected element,
    // then bump it up until it's past selected range.
    while(selectionIndex < listFiles.selectedIndices.length && 
          readIndex == listFiles.selectedIndices[selectionIndex]) {
      selectionIndex++;
      readIndex++;
    }
  }
  dataArray[writeIndex++] = dataArray[readIndex++];
}

// Remove the tail of the dataArray
if (writeIndex < dataArray.length) {
  dataArray.splice(writeIndex, dataArray.length - writeIndex);
}

编辑2009/04/04:您的移除算法仍然存在缺陷,当您移除listFiles.selectedIndices中的项目时,您会破坏arrayQueue中索引之间的对应关系以及那些listFiles.selectedIndices

要查看此内容,请尝试添加3个文件,然后执行“全选”,然后单击“删除”。它将从删除列表中的第一个文件(索引0)开始。现在已经列表中的第二个和第三个文件位于索引0和1.从listFiles.selectedIndices获取的下一个值是1 - 但是现在,是什么第三个文件位于索引1.因此,前一个文件#3被拼接出数组,使前一个第二个文件不被删除,并且在索引0处。(使用更多文件,您将看到此实现仅删除数组中的所有其他文件。)

这就是为什么我的JavaScript代码(上面)使用readIndexwriteIndex来复制数组中的条目,跳过readIndex上要删除的索引。该算法避免了丢失数组索引之间的对应关系的问题。 (它需要仔细编码以防止各种边缘条件。)我尝试了一些JavaScript代码类似于我上面写的内容;它对我有用。

我怀疑原始测试用例中的问题(删除第二个文件,然后添加另一个文件)是类似的。由于您只显示了部分代码,因此我无法确定listFiles.selectedIndicesarrayQueuefileRefList.fileList中的数组索引和数据是否始终匹配。 (但我怀疑问题是他们没有。)

顺便说一句,即使您通过适当调整数组索引值来解决使用splice()的问题,在一般情况下它仍然是O(N 2 )算法。阵列复制算法是O(N)。

答案 3 :(得分:0)

我真的需要看到整个类提供一个不同的答案,但是我会编写一个方法来处理从dataProvider中删除多个对象,并且可能将新数组指定为列表的dataProvider而不是使用绑定进行操作并在持续时间内使用相同的列表。就像我说的那样,这可能是低效的,并且需要查看问题的背景,但这就是我要做的事情9在这种情况下你需要很大的约束力。)

/**
* Returns a new Array with the selected objects removed 
*/
private function removeSelected(selectedItems:Array):Array
{
    var returnArray:Array = []
    for each(var object:Object in this.arrayQueue)
    {
        if( selectedItems.indexOf(object)==-1 )
            returnArray.push( object )
    }
    return returnArray;
}

答案 4 :(得分:-2)

您可能对此blog entry感兴趣,因为Java语言中缺少健壮的迭代器。

编程语言,你提到Javascript,不是问题,它是强调迭代器的概念,我想指出(本文实际上是关于C ++作为编程语言)。

关于为ET ++ C ++框架提供强大迭代器的[研究文档]()可能仍然有助于解决您的问题。我相信该文件可以为您提供如何解决问题的必要建议。