如何更新待办事项?

How to update todo item?

单击待办事项时,将打开编辑 window,用户可以在其中进行更改并保存。我在 ChangeNotifier 中写了一个更新函数,但是当我点击保存时,弹出一个错误: 发生这种情况是因为你使用了一个 'BuildCOntext',它不包括你选择的提供者。 但是提供程序中的其余代码有效。只有更新功能不起作用。可能是什么问题呢? 我的 ChangeNotifier:

class ListModel extends ChangeNotifier {
  List<EventModel> eventList = [];

  void addEventToList() {
    EventModel eventModel = EventModel(
      title: 'Event title ${eventList.length + 1}',
      detail: 'Event text ${eventList.length + 1}',
      id: '${eventList.length + 1}',
    );
    eventList.add(eventModel);

    notifyListeners();
  }

  EventModel? getEvent(String? id) {
    return eventList.firstOrNullWhere((event) => event.id == id);
  }

  void updateList(EventModel eventModel, String title, String detail) {
    eventModel.title = title;
    eventModel.detail = detail;

    notifyListeners();
  }
}

我的模态 window:

class EditEventBottomSheet extends StatefulWidget {
  final EventModel event;

  const EditEventBottomSheet({Key? key, required this.event}) : super(key: key);

  @override
  State<EditEventBottomSheet> createState() => _EditEventBottomSheetState();
}

class _EditEventBottomSheetState extends State<EditEventBottomSheet> {
  late final titleCntrl = TextEditingController(text: widget.event.title);
  late final detailCntrl = TextEditingController(text: widget.event.detail);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 300,
      color: Colors.amber,
      child: Center(
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: [
              const Text(
                'Change Event',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 10),
              TextField(
                controller: titleCntrl,
              ),
              const SizedBox(height: 10),
              TextFormField(
                controller: detailCntrl,
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                child: const Text('Save Edits'),
                onPressed: () {
                  Provider.of<ListModel>(context, listen: false).updateList(
                      widget.event, titleCntrl.text, detailCntrl.text);
                  // widget.event.title = titleCntrl.text;
                  Navigator.pop(context);
                },
              ),
              ElevatedButton(
                child: const Text('Close BottomSheet'),
                onPressed: () => Navigator.pop(context),
              )
            ],
          ),
        ),
      ),
    );
  }
}

我的main.dart:

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChangeNotifierProvider(
        create: (BuildContext context) => ListModel(),
        child: const HomeScreen(),
      ),
    );
  }
}

好的,所以如果你在家里设置 ChangeNotifierProvider,只有他的 child(主屏幕)会显示 ListModel(),这就是为什么在你的 EditEventBottomSheet BuildContext 没有找到 Provider,但是如果你想在另一个 Class Widget 中使用它,你必须“re-create”另一个ChangeNotifierProvider 在你的 EditEventBottomSheet 中,像这样:(你不创建另一个 ListModel,你只放置你已经创建的那个)

ChangeNotifierProvider.value(
  value: ListModel(),
  child: EditEventBottomSheet(),
)

不过不用担心,为此我建议您将 Provider 全局放置,也就是说,ALL 您的应用程序可以访问它,如何访问?好吧,不是在 body 中创建它,而是在 MaterialApp.

中创建它
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider( // something like this
      create: (BuildContext context) => ListModel(),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const HomeScreen(),
      ),
    );  
  }
}