0

我有一份食物清单。那有一个类别,subCategory1,subCategory2 等。

当用户取消选择类别项目时。他们还取消选择 subCategory1、subCategory2 项目等,因为它们是原始类别项目的子项,如下所示:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

所以我有一个 for 循环,它通过寻找子类别列表元素并像这样删除它们:

  // Remove a category item and all of its children
  if (categoryType == "category") {
    List<String> subCategory1Children = List<String>.from(
        snapshot.data.documents[gridIndex]['subCategory1Children']);

    // Remove the subcategory items
    for (int i = 0; i < foodDrinkMenuElements['subCategory1'].length; i++) {
      String subID = foodDrinkMenuElements['subCategory1'][i];
      int removalIndex = _indexOfListGridElement('subCategory1', subID);

      if (subCategory1Children.contains(subID)) {
        _removeCategoryGridItem(removalIndex, subID, 'subCategory1');
      }
    }

    //Remove the actual item being pressed
    _removeCategoryGridItem(listIndex + 1, id, categoryType);
  }

像这样调用 _removeCategoryGridItem() :

void _removeCategoryGridItem(int removalIndex, String id, String categoryType) {
  _FoodandDrinkKey.currentState.removeItem(removalIndex,
      (BuildContext context, Animation<double> animation) {
    return _buildListItem(removalIndex, animation);
  });
  foodDrinkMenuElements[categoryType].remove(id);
}

For 循环总是在删除 1 个列表项后完成。我认为这是因为函数_removeCategoryGridItem 中的return 语句。

我已经看到其他答案说将其放入列表并遍历列表,但我不知道这如何适用于此。

谢谢你的帮助

4

1 回答 1

2

For 循环总是在删除 1 个列表项后完成。我认为这是因为函数_removeCategoryGridItem 中的return 语句。

不,通常函数可以在调用函数中跳出循环的唯一方法是抛出异常。

我不知道foodDrinkMenuElements[categoryType]返回什么类型,但假设它是 a ListMap或,则在迭代集合时Set不能从集合中删除项目。

List文档中:

通常不允许在对列表执行操作时修改列表的长度(添加或删除元素)......在迭代时更改列表的长度......会破坏迭代。

Map和有类似的语言Set

我已经看到其他答案说将其放入列表并遍历列表,但我不知道这如何适用于此。

这正是您应该做的:您应该对要删除的项目进行排队,然后处理队列以避免改变您正在迭代的同一个集合:

final pendingRemoves = List<void Function()>[];

// Remove the subcategory items
for (int i = 0; i < foodDrinkMenuElements['subCategory1'].length; i++) {
  String subID = foodDrinkMenuElements['subCategory1'][i];
  int removalIndex = _indexOfListGridElement('subCategory1', subID);

  if (subCategory1Children.contains(subID)) {
    pendingRemoves.add(() =>
        _removeCategoryGridItem(removalIndex, subID, 'subCategory1'));
  }
}

// Since an index is involved, you also need to remove in reverse order so that
// the queued indices still refer to the same elements.
for (pendingRemove in pendingRemoves.reversed) {
  pendingRemove();
}

//Remove the actual item being pressed
_removeCategoryGridItem(listIndex + 1, id, categoryType);
于 2019-06-26T16:43:47.973 回答