Flutter小部件访问空提供程序对象

时间:2020-08-24 21:51:21

标签: flutter flutter-provider

我正在开发我的第一个Flutter应用程序,并且在使用Provider管理应用程序状态的方法上遇到了困难。我已经简化了事情,但是胆量是,我有一个AppModel类,其中包含用户令牌(一旦经过身份验证,他们将在发出API请求时使用该令牌)以及当前的“团队”选择。

class AppModel extends ChangeNotifier {
  Team _team;
  Team get currentTeam => _team;

  String _userToken;
  String get userToken => _userToken;

  void setUser({String token, Team team}) {
    _userToken = token;
    _team = team;
    notifyListeners();
  }

  void exitTeam() {
    _team = null;
    notifyListeners();
  }
}

可以找到用户的主要位置。如果其userToken为null,则应将其带到登录页面。如果他们有一个userToken,但是currentTeam为空,那么它们应该在团队选择屏幕上。如果他们有团队,则它们在一组页面内,从“ TeamHomePage”小部件开始,他们可以管理该团队。在顶层,我具有以下小部件构建功能:

  @override
  Widget build(BuildContext context) {
    return Consumer<AppModel>(
        builder: (context, model, _) => (model?.userToken?.isEmpty ?? true
            ? LoginScreen()
            : (model.currentTeam == null
                ? SelectTeamWidget(userToken: model.userToken)
                : TeamHomeWidget())));
  }

在TeamHomeWidget内,还有其他页面是AppModel的使用者,它们查看currentTeam属性。其中,有退出当前团队的选项,因此他们可以选择其他团队。为此,我在AppModel中这样调用exitTeam函数:

Provider.of<AppModel>(context, listen: false).exitTeam();

这几乎可以正常工作。从TeamHomeWidget调用exitTeam时,它可以工作。但是,当我在同样也是AppModel使用者的TeamHomeWidget链接的其他页面上时,由于currentTeam现在为null的事实而崩溃。但是,我打算不再渲染那些页面,因为它们应该带回到SelectTeamWidget。这种方法不正确吗?

1 个答案:

答案 0 :(得分:0)

由于您的 TeamHomeWidget也包含有使用者,因此可以使用currentTeam来执行某些操作。此使用者也正在监听AppModel的更改,如果此使用者的触发时间比顶级消费者小部件的触发时间更快,那么您的应用将崩溃。

为防止这种情况,请将顶级中的值分配给TeamHomeWidget

 @override
  Widget build(BuildContext context) {
    return Consumer<AppModel>(
        builder: (context, model, _) => (model?.userToken?.isEmpty ?? true
            ? LoginScreen()
            : (model.currentTeam == null
                ? SelectTeamWidget(userToken: model.userToken)
                : TeamHomeWidget(team: model.currentTeam))));
  }