Flutter提供者导航到另一个屏幕时失去了价值

时间:2019-12-04 09:27:09

标签: flutter provider state-management

我是Flutterprovider package的新手,所以可以提供任何帮助,所以我的main.dart文件如下:

 void main() => runApp(
      MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData.light(),
        home: ChangeNotifierProvider(
          create: (_) => InterestingMomentProvider(),
          child: Home(),
        ),
     ),
  );

这将构建我的Home小部件,因为它非常大,所以我不会将其全部发布,但是,发生的事情是单击按钮并将其传递给提供程序类的字符串并将其添加到列表中概述如下:

import 'package:flutter/widgets.dart';

class InterestingMomentProvider extends ChangeNotifier {

  List<String> _moments = [];

  List<String> get moments => _moments;

  void addMoment(String time){
    _moments.add(time);
  }

  int momentsTotal(){
    return _moments.length;
  }

}

在addMoment方法上添加一个断点,我可以确认_moments具有所有字符串。

然后我按下一个导航到另一个屏幕的按钮,导航代码如下:

Navigator.push(context, MaterialPageRoute(builder: (context) => MomentsRecorded()),);

MomentsRecorded小部件如下:

class MomentsRecorded extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Moments'),
        centerTitle: true,        
      ),
      body: Center(
        child: MomentsList()
        ),
    );
  }
}

第一个错误是:

Could not find the correct Provider<InterestingMomentProvider> above this Consumer<InterestingMomentProvider> Widget

To fix, please:

  * Ensure the Provider<InterestingMomentProvider> is an ancestor to this Consumer<InterestingMomentProvider> Widget
  * Provide types to Provider<InterestingMomentProvider>
  * Provide types to Consumer<InterestingMomentProvider>
  * Provide types to Provider.of<InterestingMomentProvider>()
  * Always use package imports. Ex: `import 'package:my_app/my_code.dart';
  * Ensure the correct `context` is being used.

然后,我将身体调整为如下所示,并且错误消失了:

 body: Center(
        child: ChangeNotifierProvider(
          create: (_) => InterestingMomentProvider(),
          child: MomentsList())
        ),

但是在MomentLists小部件中,我尝试遍历提供程序类的时刻列表,但是调试_moments为0时呢?

MomentsList小部件:

class MomentsList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<InterestingMomentProvider>(
      builder: (context, momentData, child){
        return momentData.momentsTotal() > 0 ? ListView.builder(
          itemCount: momentData.momentsTotal(),
          itemBuilder: (BuildContext context, int index) {
            final moment = momentData.moments[index];
            return ListTile(
                title: Text(moment),
            );
          }
        ) : Center(child: Text('no moments recorded'),);
      }

    );
  }
}

有人可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:4)

之所以会这样,是因为您的提供商是在<script src=http://ajaxorg.github.io/ace-builds/src/ace.js></script> <script src=http://ajaxorg.github.io/ace-builds/src/ext-modelist.js></script> <script> var modelist = ace.require("ace/ext/modelist") var dom = ace.require("ace/lib/dom") // using buildDom from ace, but any other method of constructing dom can be used here var modePicker = dom.buildDom(["select", { value: "ace/mode/text", onchange: function() { editor.setOption("mode", this.value); } }, modelist.modes.map(function(x) { return ["option", { value: x.mode }, x.caption]; }) ], document.body); var editor = ace.edit(null, { maxLines: 10, minLines: 5 }) document.body.appendChild(editor.container) </script>的{​​{1}}属性中定义的,因此,当您更改路由时,提供商也会被删除。

解决方案:将提供者移动到MaterialApp上方,如下所示:

home

如果您担心这是不对的-checkout the docs, they doing the same