簡體   English   中英

Flutter:當我熱重載我的 Provider 時創建新的 object

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM