我有一个简化的情况,我不能在Flutter中工作:一个MobX可观察对象(Book)有一个我也想观察的章节列表,所以我的UI被重新绘制以显示一个新创建的章节。
在现实中,我有更复杂的模型,这只是我设法展示我的问题的最简单的情况。
当我创建一个新的章节时,新的章节不会出现在列表中,但是如果我回到主页,它会出现在章节列表中。
在我的应用程序中,我不能将Book中的 chapters 属性更改为ObservableList,因为其他原因:final ObservableList<Chapter> chapters;
是一个禁忌。
我在stackoverflow中查找了几个类似的问题,但在其中任何一个上都找不到解决我的问题的方法。
如何观察当前图书中的章节,以便在创建新章节后正确更新UI?
我的模特:
class Book {
final String title;
final List<Chapter> chapters;
Book(this.title, this.chapters);
}
class Chapter {
final String title;
Chapter(this.title);
}
字符串
我的MobX商店:
import 'book.dart';
import 'package:mobx/mobx.dart';
part 'book_editor_store.g.dart';
class BookEditorStore = BookEditorStoreBase with _$BookEditorStore;
abstract class BookEditorStoreBase with Store {
@readonly
Book _currentBook = Book('', []);
@readonly
Chapter? _currentChapter;
@computed
int get chapterCount => _currentBook?.chapters.length ?? 0;
@computed
List<Chapter> get chapters => _currentBook?.chapters ?? [];
@action
setBook(Book book) {
_currentBook = book;
}
@action
addChapter(Chapter chapter) {
_currentBook?.chapters.add(chapter);
}
}
型
我的主.dart:
import 'book_editor_page.dart';
import 'book_editor_store.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return Provider(
create: (context) => BookEditorStore(),
child: MaterialApp(
title: 'MobX reactions',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MainPage(),
),
);
}
}
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Main Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const BookEditorPage()),
);
},
child: const Text('Editor'),
),
),
);
}
}
型
我的BookEditorPage:
import 'book_editor_store.dart';
import 'book.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class BookEditorPage extends StatelessWidget {
const BookEditorPage({super.key});
@override
Widget build(BuildContext context) {
final bookEditorStore = Provider.of<BookEditorStore>(context);
return Scaffold(
appBar: AppBar(
title: const Text('Book Editor'),
),
body: Column(
children: [
Observer(
builder: (_) => ListView.builder(
shrinkWrap: true,
itemCount: bookEditorStore.chapterCount,
itemBuilder: (_, index) {
final chapter = bookEditorStore.chapters[index];
return ListTile(
title: Text(chapter.title),
);
},
),
),
ElevatedButton(
onPressed: () => addChapter(context, bookEditorStore),
child: const Text('Add Chapter'),
),
],
),
);
}
void addChapter(BuildContext context, BookEditorStore bookEditorStore) {
final TextEditingController titleController = TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('New Chapter'),
content: TextFormField(
controller: titleController,
decoration: const InputDecoration(hintText: 'Enter chapter title'),
autofocus: true,
),
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Create'),
onPressed: () {
final String title = titleController.text;
if (title.isNotEmpty) {
bookEditorStore.addChapter(Chapter(title));
Navigator.of(context).pop();
}
},
),
],
);
},
);
}
}
型
1条答案
按热度按时间ttp71kqs1#
它一点也不优雅,但它很有效:在商店内创建一个单独的可观察章节列表(并注意在可观察副本中反映真实的Book.chapters列表中的任何更改)。
只需将 BookEditorStore 更改为:
字符串
其余的保持不变,它的工作!
我暂时不接受我的答案,希望有人能提出一个不那么笨拙的解决方案。