Dart 当我关注TextField-Bloc模式时,小部件重新呈现

Dart 当我关注TextField-Bloc模式时,小部件重新呈现,dart,flutter,Dart,Flutter,我使用一个BLoC来保持两个嵌套的全屏对话框之间的状态 当我按下第一个屏幕时,我正在初始化bloc,就像这样 return FloatingActionButton( child: Icon(Icons.add), onPressed: () { Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) => ProductBlocP

我使用一个BLoC来保持两个嵌套的
全屏对话框之间的状态

当我按下第一个屏幕时,我正在初始化bloc,就像这样

return FloatingActionButton(
      child: Icon(Icons.add),
      onPressed: () {
        Navigator.of(context).push(MaterialPageRoute(
          builder: (BuildContext context) => ProductBlocProvider(child: ProductEntryScreen()),
          fullscreenDialog: true
        ));
      },
    );
ProductEntryScreen
有一组
文本字段
和一个按钮,可以打开一个新的
全屏对话框
。这个新屏幕也有
文本字段
。 我遇到的问题是,每次我在第二个
FullScreenDialog
TextField
上写东西时,启动
ProductBlocProvider
的onPressed函数都会再次运行

这种重新运行会导致集团创建一个新实例,因此我最终失去了状态

我想做什么? 也许我做错了,所以我会解释我想要达到的目标


填充所有字段时,我想在两个
全屏对话框之间保持状态,完成后,我想按一个按钮发送所有数据(两个屏幕)到数据库。

问题是,我在
materialpage路径的builder函数的提供者内创建了bloc的实例

该生成器函数被反复调用,并且每次都创建一个新的bloc实例。解决方案是从builde函数中删除bloc实例的创建,如下所示:

return FloatingActionButton(
      child: Icon(Icons.add),
      onPressed: () {
        //Here I create the instance
        var _bloc = ProductBloc();
        Navigator.of(context).push(MaterialPageRoute(
          //And I pass the bloc instance to the provider
          builder: (BuildContext context) => ProductBlocProvider(bloc: _bloc, child: ProductEntryScreen()),
          fullscreenDialog: true
        ));
      },
    );
这个包裹可能对你有帮助。get_它是一个服务定位器库,使用地图存储注册的对象;因此,它以O(1)的复杂度提供访问,这意味着它的速度非常快。这个包附带了一个singleton
GetIt
,您可以像这样使用它

//创建一个全局变量(传统上称为sl或定位器)
final sl=GetIt.instance;//还有一个速记。我
// ...
//然后,可能在一个名为initDi()的全局函数中,
//您可以注册您的依赖项。
sl.registerLazySingleton(()=>ProductBloc());
registerLazySingleton()或registerSingleton()将始终 返回相同的实例;懒散地(即,第一次呼叫时) 或分别在应用程序启动时

如果每次都要创建一个新实例,请改用registerFactory()(我把它放在这里,尽管它并不完全是您想要的)。 比如说,

sl.registerFactory(()=>ValidatorCubit());
它可以这样访问

MultiBlocProvider(
供应商:[
//类型在这里被推断出来
BlocProvider库,但可以在任何地方工作,即使在非颤振飞镖项目中也是如此。
如果您需要更多功能,请务必阅读此软件包的文档。它有很好的文档记录,并且包含(几乎)您可能需要的所有功能,包括范围

此外,这种方法允许您使用接口模式,使代码更易于维护和测试,因为您只需更改一个位置即可使用不同的实现