从数据库中获取状态对象

时间:2019-11-12 11:29:53

标签: flutter flutter-provider

我想在启动时从数据库获取状态。我在第一个窗口小部件上将provider与ChangeNotivierProvider一起使用。包含代码以供澄清。

这是我的主要方法,它具有提供我计划在应用程序中使用的状态的小部件:

void main() => runApp(
    ChangeNotifierProvider(
            child: MyApp(),
            builder: (context) => StateDao.get(),
    ),
}

我的DAO只是从数据库返回状态(我使用sembast,但也可以很容易地是sqflite或Firebase)

Future<State> get() async { 
    // Database logic
}

状态只是扩展ChangeNotifier的对象

class State extends ChangeNotifier {
    // Getters, setters, changeNotifiers etc.
}

这将不起作用,因为我无法在 ChangeNotifierProvider 的生成器方法中调用 async 方法。应该如何,何时何地进行初始化?据我了解,异步调用不应在任何构建方法中进行。我尝试覆盖了提供上下文访问的didChangeDependencies,但无法克服构建器方法限制中的异步调用。

1 个答案:

答案 0 :(得分:1)

您可以在 initState 中初始化值。例如,您可以存储 Future 对象,并在解析值后使用 FutureBuilder 来构建窗口小部件:

  Future<State> futureState;

  @override
  void initState() {
    // Calling async method and storing Future object
    futureState = StateDao.get();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<State>(
      future: futureState,
      builder: (context, snapshot) {
        // No data yet, showing loader
        if (!snapshot.hasData) {
          return CircularProgressIndicator();
        }

        return ChangeNotifierProvider(
          child: MyApp(),
          builder: (context) => snapshot.data,
        );
      },
    );
  }

另一种类似的方法是使用StreamController和StreamBuilder:

  final StreamController<State> stateStream = StreamController<State>();

  @override
  void initState() {
    // Calling async method and setting callback to add data to the stream
    StateDao.get().then((v) => stateStream.add(v));
    super.initState();
  }

  @override
  void dispose() {
    // Closing the sink
    stateStream.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<State>(
      stream: stateStream.stream,
      builder: (context, snapshot) {
        // No data yet, showing loader
        if (!snapshot.hasData) {
          return CircularProgressIndicator();
        }

        return ChangeNotifierProvider(
          child: MyApp(),
          builder: (context) => snapshot.data,
        );
      },
    );
  }

如果您需要更复杂的体系结构,则可能需要看看BLoC,它是Flutter社区中非常流行的体系结构。