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

Flutter 颤振小部件访问空提供程序对象,flutter,flutter-provider,Flutter,Flutter Provider,我正在开发我的第一个颤振应用程序,在使用提供者管理应用程序状态的方法上遇到了困难。我已经简化了一些事情,但关键是我有一个AppModel类,它包含一个用户令牌,一旦通过身份验证,他们将在发出API请求时使用该用户令牌,以及他们当前的“团队”选择 class AppModel extends ChangeNotifier { Team _team; Team get currentTeam => _team; String _userToken; String get us

我正在开发我的第一个颤振应用程序,在使用提供者管理应用程序状态的方法上遇到了困难。我已经简化了一些事情,但关键是我有一个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())));
  }
@覆盖
小部件构建(构建上下文){
退货消费者(
生成器:(上下文,模型,)=>(模型?.userToken?.isEmpty??true
?登录筛选()
:(model.currentTeam==null
?选择TeamWidget(userToken:model.userToken)
:TeamHomeWidget());
}
在TeamHomeWidget中,还有其他页面是AppModel的使用者,它们查看currentTeam属性。其中,有退出当前团队的选项,以便他们可以选择不同的团队。为此,我在AppModel中调用exitTeam函数,如下所示:

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

这几乎达到了预期效果。从TeamHomeWidget调用exitTeam时,它会工作。然而,当我在链接TeamHomeWidget的任何其他页面上时,也就是AppModel的消费者,我会因为currentTeam现在为空而崩溃。但是,我打算不再呈现这些页面,因为它们应该被带回SelectTeamWidget。这种方法不正确吗?

因为您的TeamHomeWidget也使用消费者包装,并使用currentTeam做一些事情。此消费者还会监听AppModel的更改,如果此消费者的触发速度比您的顶级消费者小部件快,则您的应用程序将崩溃

要防止出现这种情况,请将顶层中的值分配给TeamHomeWidget

@覆盖
小部件构建(构建上下文){
退货消费者(
生成器:(上下文,模型,)=>(模型?.userToken?.isEmpty??true
?登录筛选()
:(model.currentTeam==null
?选择TeamWidget(userToken:model.userToken)
:TeamHomeWidget(团队:model.currentTeam));
}

因为您的TeamHomeWidget也包含一个消费者并使用currentTeam做一些事情。此消费者还会监听AppModel的更改,如果此消费者的触发速度比您的顶级消费者小部件快,则您的应用程序将崩溃

要防止出现这种情况,请将顶层中的值分配给TeamHomeWidget

@覆盖
小部件构建(构建上下文){
退货消费者(
生成器:(上下文,模型,)=>(模型?.userToken?.isEmpty??true
?登录筛选()
:(model.currentTeam==null
?选择TeamWidget(userToken:model.userToken)
:TeamHomeWidget(团队:model.currentTeam));
}

这非常有助于我更好地了解我的应用程序中发生了什么。最终,我所做的是,一旦我导航到其他路径,它们将完全从小部件树中替换具有消费者逻辑的路径。我在团队上下文路由中添加了一个导航器,使这个小部件始终处于顶层,从而解决了这个问题。干杯这对我更好地理解我的应用程序中发生的事情非常有帮助。最终,我所做的是,一旦我导航到其他路径,它们将完全从小部件树中替换具有消费者逻辑的路径。我在团队上下文路由中添加了一个导航器,使这个小部件始终处于顶层,从而解决了这个问题。干杯