1

我有以下代码在其中生成项目列表(数据取自 Firebase)。我想实现一个删除项目的功能,但我不知道如何访问列表以及如何删除项目:

class _MyOfferState extends State<MyOffer> {
  List<Widget> items = [];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
...
          body: SingleChildScrollView(
            child: Column(
              children: [
                StreamBuilder<QuerySnapshot>(
                  stream: FirebaseFirestore.instance
                      .collection('Offers')
                  builder: (BuildContext context, snapshot) {
                      snapshot.data.docs.forEach((element) {
                        element.get('items').forEach((item) {
                          String _name = element['name'];
                          String _category = item['category'];

                          items.add(offer(name, category, context,...));

                        });
            }
                      );
                    }
                    return new Column(
                      children: List.unmodifiable(() sync* {
                        yield* items;
                      }()),
                    );
                  },
          ),
        
  }
}

这是一个动态类,我有 GestureDetector。当用户点击它时,该项目应该被删除。

dynamic offer(name, category, context,) {

  return GestureDetector(
      child: Container(
        child: Row(
                    children: [
                      Text(name),
                      Text(category),
          ],
        ),
      ),
    ),
    onTap: () {
      
 // remove item should be here
    },
  );
}
4

3 回答 3

0

您的列表是由Stream您提供给您的数据构建的StreamBuilder,请创建您需要更改 Stream 值的新列表,我建议将 FirebaseFirestore.instance.collection('Offers')实例保留在流中并修改流。

    class _MyOfferState extends State<MyOffer> {
      List<Widget> items = [];
StreamController _controller = StreamController();

 @override
  void initState() {
    super.initState();
_controller.addStream( FirebaseFirestore.instance
                      .collection('Offers').snapshots());    
  }


// dont forgot to close stream
 @override
  void dispose() {
    _controller.close();
    super.dispose();
  }


      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
    ...
                  body: SingleChildScrollView(
                    child: Column(
                      children: [
                        StreamBuilder<QuerySnapshot>(
                          stream: _controller.stream,
                          builder: (BuildContext context, snapshot) {
                              snapshot.data.docs.forEach((element) {
                                element.get('items').forEach((item) {
                                  String _name = element['name'];
                                  String _category = item['category'];
        
                                  items.add(offer(name, category, context,(){
// remove function is here
  snapshot.data.docs.removeWhere((e) => e.id == element.id);
 _controller.add(snapshot.data);
});
      


                            });
                }
                          );
                        }
                        return new Column(
                          children: List.unmodifiable(() sync* {
                            yield* items;
                          }()),
                        );
                      },
              ),
            
      }
    }

也传递onTap给您的小部件功能

dynamic offer(name, category, context, onTap) {

  return GestureDetector(
      child: Container(
        child: Row(
                    children: [
                      Text(name),
                      Text(category),
          ],
        ),
      ),
    ),
    onTap: onTap,
  );
}
于 2021-05-21T13:40:17.713 回答
0

您需要传递项目的索引并按索引删除:

int index = 0;
snapshot.data.docs.forEach((element) {
                        element.get('items').forEach((item) {
                          String _name = element['name'];
                          String _category = item['category'];

                          items.add(offer(index, name, category, context,...));
                          index++;
                        });



Widget offer(int index, string name, string category, BuildContext context,) {

  return GestureDetector(
      child: Container(
        child: Row(
                    children: [
                      Text(name),
                      Text(category),
          ],
        ),
      ),
    ),
    onTap: () {
      
 // remove item should be here
items.removeAt(index);
setState((){});
    },
  );
}

            }
                      );
                    }
                    return new Column(
                      children: List.unmodifiable(() sync* {
                        yield* items;
                      }()),
                    );
于 2021-05-19T08:18:57.907 回答
0

从内部删除报价并不是最佳做法,但您可以通过多种方式完成它。我能想到的第一个是在创建这样的报价时传递一个将其删除的函数:

items.add(offer(name, category, context,..., () {
   setState(() {
      FirebaseFirestore.instance
                      .collection('Offers')
                      .doc(element['id'])
                      .delete();
      items.remoev(index);
   });
}));

您需要事先创建索引并每次都增加它,但我不建议这样做。我这样做的方法是将报价更改为:

dynamic offer(name, category, context,) {

  return Container(
        child: Row(
           children: [
              Text(name),
              Text(category),
          ],
        ),
      );
}

在创建报价时,将其包装在 GestureDetector 中,如下所示:

items.add(GestureDetector(
             child: offer(name, category, context,...)),
             onTap: () {
                setState(() {
                    FirebaseFirestore.instance
                      .collection('Offers')
                      .doc(element['id'])
                      .delete();
                    items.remoev(index);
                });
             },
         );

你必须对索引做同样的事情,但我认为这是一种更好的方法,因为孩子对父母没有权力并且不能改变它的状态,这是一个很好的做法。

于 2021-05-25T08:00:00.207 回答