从数据库中获取状态对象

Fetch state-object from database

我想在启动时从数据库中获取我的状态。我在我的第一个小部件中使用提供程序和 ChangeNotivierProvider。包含用于说明的代码。

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

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

我的 DAO 只是 returns 来自数据库的状态(我使用 sembast,但也可以很容易地成为 sqflite 或 Firebase)

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

State 只是一个扩展 ChangeNotifier 的对象

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

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

可以在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 社区中非常流行的架构。