在颤动中使用 list.remove(element) 时未在列表中删除项目

Posted

技术标签:

【中文标题】在颤动中使用 list.remove(element) 时未在列表中删除项目【英文标题】:item not removed in list when use list.remove(element) in flutter 【发布时间】:2021-12-26 14:59:22 【问题描述】:

添加元素后,我无法删除列表中的项目。

  List<CartItem> _items = [];
  FirebaseFirestore? _instance;

  void add(BuildContext context, CartItem item) 
    _items.add(item);

    AuthService authService = Provider.of<AuthService>(context, listen: false);
    Map<String, dynamic> cartMap = Map();
    _items.forEach((CartItem item) 
      cartMap['title'] = (item.product as Product).title;
      cartMap['name'] = (item.product as Product).name;
    );

    _instance = FirebaseFirestore.instance;
    _instance!
        .collection('cart')
        .doc(authService.getCurrentUser()) //need to get logged in account's id
        .update(
      'cartProduct': FieldValue.arrayUnion([cartMap])
    ).then((value) 
      print(_items.length);
      notifyListeners();
    );
  


  void remove(BuildContext context, CartItem item) 
    _items.remove(item);

    AuthService authService = Provider.of<AuthService>(context, listen: false);
    Map<String, dynamic> cartMap = Map();
    cartMap['title'] = (item.product as Product).title;
    cartMap['name'] = (item.product as Product).name;
    _instance = FirebaseFirestore.instance;
    _instance!.collection('cart').doc(authService.getCurrentUser()).update(
      'cartProduct': FieldValue.arrayRemove([cartMap]),
    ).then((value) 

      print(_items.length);
      notifyListeners();
    );
  

添加(context, widget.product) 并打印 _items.length 后,结果为 1 但是,在我执行 remove(context, widget.product) 并打印 _items.length 之后,结果仍然是 1。

Consumer<CartService>(
            builder: (context, cart, child) 
              Widget renderedButton;
              if (cart.isProductAddedToCart(widget.product) == false) 
                renderedButton = DefaultButton(
                  text: "Participate",
                  press: () 
                    print(cart.isProductAddedToCart(widget.product));
                    cartService.add(context, CartItem(product: widget.product));
                    print(cart.isProductAddedToCart(widget.product));
                  ,
                );
               else 
                renderedButton = DefaultButton(
                  text: "Delete",
                  press: () 
                    print(cart.isProductAddedToCart(widget.product));
                    cartService.remove(
                        context, CartItem(product: widget.product));
                    print(cart.isProductAddedToCart(widget.product));
                  ,
                );
              
              return renderedButton;

与上面的代码一样,remove() 方法应该删除使用 add() 方法添加到列表中的相同项目。

【问题讨论】:

你修改过 .add 和 .remove 函数吗? 您确定要添加的item 与您要删除的item 的实例相同吗?如果没有,项目对象/类是否具有相等性和哈希码实现来比较两个项目并确保它们相等?也许使用_items.removeWhere((_item) =&gt; _item.property == item.property); 更容易,其中属性可以是产品的ID。让我知道这是否能解决您的问题,以便我将其发布为答案。 @osaxma 你是救生员,非常感谢。成功了! @RickyKim 很高兴为您提供帮助。我将我的评论添加为答案,因此您可以将其标记为已接受。 【参考方案1】:

只需将 remove() 更新为:(仅更改 _items.remove(item); 位置)

void remove(BuildContext context, CartItem item) 

AuthService authService = Provider.of<AuthService>(context, listen: false);
Map<String, dynamic> cartMap = Map();
cartMap['title'] = (item.product as Product).title;
cartMap['name'] = (item.product as Product).name;
_instance = FirebaseFirestore.instance;
_instance!.collection('cart').doc(authService.getCurrentUser()).update(
  'cartProduct': FieldValue.arrayRemove([cartMap]),
).then((value) 

/// todo check firebase collection's deletion success first
_items.remove(item);

  print(_items.length);
  notifyListeners();
);

【讨论】:

【参考方案2】:

您要添加到列表中的项目可能与您要删除的项目不同。确保项目对象/类具有相等性和哈希码实现,以正确比较这两个项目。

如果您无法控制对象,则以下方法可能是更简单的替代方法:

_items.removeWhere((_item) => _item.property == item.property);

^ 其中property 可以是产品的ID。

【讨论】:

以上是关于在颤动中使用 list.remove(element) 时未在列表中删除项目的主要内容,如果未能解决你的问题,请参考以下文章

List中remove()方法的陷阱,被坑惨了!

List 集合 remove 对象时出现 ConcurrentModificationException

java中list.remove方法使用

列表 List remove()方法

在foreach循环中使用remove报ConcurrentModificationException异常原因

Java中List 删除元素