Flutter:带有初始网络请求的 ChangeNotifierProvider

Flutter: ChangeNotifierProvider with an initial network request

我有一个代表电影列表的小部件,在我的模型中我有 getMovies() 函数,它从网络请求中检索电影列表:

enum MovieListState { IDLE, LOADING, ERROR }

class MovieListModel extends ChangeNotifier {
  MovieListModel(this._client);

  GatewayClient _client;

  MovieListState _viewState = MovieListState.LOADING;

  MovieListState get viewState => _viewState;

  set viewState(MovieListState value) {
    _viewState = value;
    notifyListeners();
  }

  Future<List<Movie>> getMovies() async {
    try {
      viewState = MovieListState.LOADING;
      var movies = await _client.getMovies();
      viewState = MovieListState.IDLE;
      return movies;
    } on KoException catch (e) {
      viewState = MovieListState.ERROR;
      throw e;
    }
  }
}

然后我想根据请求的状态从小部件构建布局:

@override
  Widget build(BuildContext context) {
    state = Provider.of<AppState>(context);
    var model = MovieListModel(Provider.of<GatewayClient>(context));

    return ChangeNotifierProvider<MovieListModel>.value(
        value: model,
        child: Consumer<MovieListModel>(builder: (context, model, child) {
          if (model.viewState == MovieListState.IDLE) {
            return _getList(); // Method which generates the content with the retrieved values
          } else if (model.viewState == MovieListState.LOADING) {
            return Center(
              child: CircularProgressIndicator(),
            );
          } else {
            return Center(
              child: Text(_static.translate(context).movieListError),
            );
          }
        }));
  }

问题是,如何在widget初始化的一开始就触发网络调用getMovies()?我尝试在不同点手动调用 getMovies() 方法,但我遇到了错误,或者每次小部件调用其 build() 方法时调用都在重复。

提前致谢。

使用 FutureProvider 修复:

  @override
  Widget build(BuildContext context) {
    return FutureProvider<List<Movie>>.value(
      value: _model.getMovies(),
      initialData: List<Movie>(),
      catchError: (context, error) {
        return null;
      },
      child: Consumer<List<Movie>>(
        builder: (context, data, widget) {
          // ...
        },
      ),
    );
  }