[英]Flutter: When I hot reload my Provider create new object
這是我真正的第一個問題,所以如果我犯了錯誤,我很抱歉。 我發現了一些關於我的問題的類似問題,但沒有一個能真正解決我的問題。
所以我在我的項目中使用 Provider 4.0.2,當通過我的應用程序導航時它工作正常,但是當我嘗試熱重載時我的 Provider 丟失了 state 和我的 object 重新開始。
這就是我的實現方式:
主要.dart
void main() {
Provider.debugCheckInvalidValueType = null;
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<ExpenseDAO>(create: (context) => ExpenseDAO()),
ChangeNotifierProxyProvider<ExpenseDAO, ExpensesData>(
update: (context, dao, expensesData) => ExpensesData(dao: dao)),
ChangeNotifierProvider<User>(create: (context) => User()),
],
child: MyApp(),
),
);
}
費用_data.dart
class ExpensesData with ChangeNotifier {
ExpensesData({@required this.dao}) {
print('new object');
}
final List<Expense> _expenses = [];
final ExpenseDAO dao;
bool _isLoaded = false;
bool get isLoaded => _isLoaded;
UnmodifiableListView<Expense> get expenses => UnmodifiableListView(_expenses);
saveExpense(Expense expense) async {
await dao.insertExpense(expense);
await loadList(expense.userId);
notifyListeners();
}
loadList(String userId) async {
_expenses.clear();
_expenses.addAll(await dao.expenses(userId));
_isLoaded = true;
}
那就是我的問題所在。 熱重載時我得到一個新的 object,我可以通過在控制台熱重載時打印“新對象”來看到這一點,之后費用列表為空,我的屬性“isLoaded”返回 false。
費用_屏幕.dart
class ExpensesScreen extends StatefulWidget {
static const String id = 'expense_screen';
@override
_ExpensesScreenState createState() => _ExpensesScreenState();
}
class _ExpensesScreenState extends State<ExpensesScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kColorBackground,
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'Expenses',
style: TextStyle(color: Colors.black),
),
),
body: Container(
child: Column(
children: <Widget>[
Center(
child: Consumer<ExpensesData>(
builder: (context, expensesData, child) {
return ListView.separated(
itemBuilder: (context, index) {
return Text(
'Tag = ${expensesData.expenses[index].category} '
'// Value = ${expensesData.expenses[index].value}');
},
separatorBuilder: (context, index) => Divider(),
itemCount: expensesData.expenses.length);
},
),
),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.add,
size: 40,
),
onPressed: () {
Navigator.pushNamed(context, AddExpenseScreen.id);
},
),
);
}
}
你們能幫幫我嗎? 我真的認為我的代碼有問題,但我不知道它是什么。
閱讀ChangeNotifierProxyProvider
文檔,它明確表示:
DON'T create the ChangeNotifier inside update directly.
This will cause your state to be lost when one of the values used updates
您違反的是:
update: (context, dao, expensesData) => ExpensesData(dao: dao)),
您應該將新的dao
object 注入到先前創建的ExpensesData
object 中,例如(使dao
不再是final
版本):
update: (context, dao, expensesData) => expensesData.dao = dao),
或者
update: (context, dao, expensesData) => expensesData.update(dao)),
這取決於您的特定代碼和品味。
您還可以在 create 屬性中傳遞 first model 的實例,並在 update 屬性中返回相同的實例:
void main() {
Provider.debugCheckInvalidValueType = null;
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<ExpenseDAO>(create: (context) =>
ExpenseDAO()),
ChangeNotifierProxyProvider<ExpenseDAO, ExpensesData>(
create: (context) => ExpensesData(Provider.of<ExpensesDao>(context,
listen:false))
update: (context, dao, expensesData) => expensesData,
ChangeNotifierProvider<User>(create: (context) => User()),
],
child: MyApp(),
),
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.