当我专注于TextField-Bloc Pattern时,小部件重新呈现

时间:2018-08-21 20:17:56

标签: dart flutter

我正在使用BLoC来保持两个嵌套FullScreenDialogs之间的状态。

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

return FloatingActionButton(
      child: Icon(Icons.add),
      onPressed: () {
        Navigator.of(context).push(MaterialPageRoute(
          builder: (BuildContext context) => ProductBlocProvider(child: ProductEntryScreen()),
          fullscreenDialog: true
        ));
      },
    );

ProductEntryScreen有一堆TextFields和一个按钮,然后打开一个新的FullScreenDialog。此新屏幕还具有TextFields。 我遇到的问题是,每次我在第二个TextField上的FullScreenDialog上书写时,启动ProductBlocProvider的onPressed函数都会再次运行。

重新运行导致Bloc创建一个新实例,所以我最终失去了状态。

我想做什么? 也许我做错了,所以我将解释我要实现的目标。

在填充所有字段时,我想保持两个FullScreenDialogs之间的状态,完成后,我想按一个将所有数据(两个屏幕)都发送到数据库的按钮。 / p>

2 个答案:

答案 0 :(得分:2)

问题是我在"query": { "bool": { "should": [ { "multi_match": { "query": "<here your query>", "fields": ["name", "info", "description"], "type": "cross_fields", "operator": "AND" } }, { "multi_match": { "query": "<here your query>", "fields": ["name", "info", "description"], } } ] } } 的builder函数中的提供者内部创建了bloc的实例。

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

MaterialPageRoute

答案 1 :(得分:0)

get_it 可能对您有所帮助。 get_it 是一个服务定位器库,使用一个 Map 来存储注册的对象;因此,它以 O(1) 的复杂性提供访问,这意味着它非常快。该包带有一个单例 GetIt,您可以像这样使用,

// Create a global variable (traditionally called sl or locator)
final sl = GetIt.instance; // There is also a shorthand GetIt.i

// ...

// Then, maybe in a global function called initDi(), 
// you could register your dependencies.
sl.registerLazySingleton(() => ProductBloc()); 

registerLazySingleton() 或 registerSingleton() 将始终 返回相同的实例;懒惰(即第一次调用时) 或分别在应用启动时。

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

sl.registerFactory(() => ValidatorCubit());

它可以像这样访问,

MultiBlocProvider(
  providers: [
    // The type is inferred here
    BlocProvider<AuthenticationBloc>(create: (_) => sl()),
    // The type is explicitly given here
    BlocProvider(create: (_) => sl<ProductsBloc>()),
  ],
  child: ProductsScreen(),
),

此示例主要向您展示如何使用 flutter_bloc 库完成此操作,但 get_it 可以在任何地方使用,即使在非 Flutter dart 项目中也是如此。 如果您需要更多功能,请务必阅读此包的文档。它有据可查,并且(几乎)包含您可能需要的所有功能,包括范围。

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