首页 > 解决方案 > Flutter/Riverpod 删除项目和导航 - 最佳实践

问题描述

我在颤振应用程序中使用 Riverpod。我在来自 firebase 数据库的列表视图中显示项目:

final eventStream = StreamProvider.autoDispose<Event?>(
        (ref) => ref.watch(eventService).eventStream(eventId: eventId));

Consumer(
          builder: (context, watch, child) {
                data: (Event? event) { LISTVIEW }
                loading: () => const CircularProgressIndicator(),
                error: (error, stackTrace) => Text(stackTrace.toString()));
          },

问题是:当我删除屏幕上的事件(eventId)时,消费者正在侦听流并导航到另一个屏幕,然后它显示错误(stackTrace),因为消费者不再找到该元素。我用一个简单的功能删除了该项目:

void deleteEvent(BuildContext context) async {
    context.read(eventService).deleteEvent(eventId: eventId);
    await Navigator.push(
        context,
        MaterialPageRoute<Widget>(
        builder: (context) =>
        CreateEventScreen()));
}

现在我的问题是:如何处理那个用例?

标签: firebaseflutterriverpod

解决方案


import 'package:dede_app/main.dart';
import 'package:dede_app/model/event.dart';
import 'package:dede_app/screens/add_item_to_event_screen/event_item_form_container.dart';
import 'package:dede_app/screens/add_item_to_event_screen/event_item_list_widget.dart';
import 'package:dede_app/screens/create_event_screen/create_event_screen.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:share_plus/share_plus.dart';
import 'drop_down_widget.dart';

class AddItemsToEventScreen extends StatelessWidget {
  AddItemsToEventScreen({Key? key, required this.eventId}) : super(key: key);

  // Declare a field that holds the Todo.
  final String eventId;

  @override
  Widget build(BuildContext context) {
    final eventStream = StreamProvider.autoDispose<Event?>(
        (ref) => ref.watch(eventService).eventStream(eventId: eventId));

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.lightGreen,
        // title: Text(AppLocalizations.of(context)!.addItemsToEventTitle),
        title: DropDownWidget(),
      ),
      body: Column(children: <Widget>[
        Consumer(
          builder: (context, watch, child) {
            final event = watch(eventStream);
            return event.when(
                data: (Event? event) {
                  if(event!.id != null) {
                    return EventItemFormContainer(context, event);
                  } else {
                    return const Text('Kein gültiger Event');
                  }
                },
                loading: () => const CircularProgressIndicator(),
                error: (error, stackTrace) => Text(stackTrace.toString()));
          },
        ),
        Expanded(
          child: SingleChildScrollView(
            child: EventItemList(eventId: this.eventId),
          ),
        ),
      ]),
      bottomNavigationBar: Container(
        height: 80,
        margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
        child: Row(
          children: <Widget>[
            Container(
              width: 66,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[const Icon(Icons.edit, color: Colors.black)],
              ),
            ),
            Container(
              width: 80,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  ElevatedButton(
                      style: ButtonStyle(
                        elevation : MaterialStateProperty.all(0),
                        backgroundColor: MaterialStateProperty.all( Colors.transparent),
                      ),
                      onPressed: () => deleteEvent(context),
                      child: const Icon(Icons.delete, color: Colors.black))],
              ),
            ),
            Expanded(
              child: Container(
                alignment: Alignment.centerRight,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    ElevatedButton(
                      onPressed: () {Share.share('Hier die URL zum Event einfügen', subject: 'Event xyz');},
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          const Icon(
                            Icons.send,
                            color: Colors.black,
                          ),
                          Text(AppLocalizations.of(context)!
                              .addItemsToEventSendList),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  void deleteEvent(BuildContext context) async {
    context.read(eventService).deleteEvent(eventId: eventId);
    await Navigator.push(
        context,
        MaterialPageRoute<Widget>(
        builder: (context) =>
        CreateEventScreen()));
  }
}

推荐阅读