0

我正在使用 ScopedModel 模式,但我也很感兴趣如何在类似的 Provider 模式中解决同样的问题。

目前,我有一个 ScopedModel,其中暴露了一个名为loggedIn 的布尔值。当 FirebaseonAuthStateChanged 流更改用户登录状态时,我的 ScopedModel 会更改该布尔值,并调用 NotifyListeners。所有直截了当的东西。

现在,我对基于此 ScopedModel 推送或弹出路由的最佳方式感到困惑。

我所有登录的屏幕(需要用户的屏幕)都应该在构建方法中包含以下代码吗?

WidgetsBinding.instance.addPostFrameCallback((_) {
  if (!auth.hasUser)
    Navigator.of(context).pushNamedAndRemoveUntil('/entry', (Route<dynamic> route) => });
});

在每个屏幕上都有这段代码似乎有点过分。有没有一种方法可以只在某处定义此日志屏幕更改行为一次?

4

1 回答 1

0

为它创建一个小部件;)


class Validation extends StatefulWidget {
  final Function validator;
  final Widget child;

  const Validation({Key key, this.validator, this.child}) : super(key: key);
  @override
  _ValidationState createState() => _ValidationState();
}

class _ValidationState extends State<Validation> {
  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) { 
      widget.validator();
    });
    super.initState();
  }
  
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

现在到处使用它

  @override
  Widget build(BuildContext context) {
    return Validation(
      validator: (){
        if (!auth.hasUser){
          Navigator.of(context).pushNamedAndRemoveUntil('/entry', (Route<dynamic> route) => false);
        }          
      },
      child: MyAwesomePage(),
    );
  }

如果验证在任何地方都相同,您可以进一步简化,或者根据所需的验证创建多个验证小部件,

适合您的情况



class LoginValidation extends StatefulWidget {
  final String routeIfNotLoggedIn;
  final Widget child;

  const LoginValidation({Key key, this.routeIfNotLoggedIn, this.child}) : super(key: key);
  @override
  _LoginValidationState createState() => _LoginValidationState();
}

class _LoginValidationState extends State<LoginValidation> {
  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      if (!auth.hasUser){
        Navigator.of(context).pushNamedAndRemoveUntil(widget.routeIfNotLoggedIn, (Route<dynamic> route) => false);
      }
    });
    super.initState();
  }
}

并使用它


  @override
  Widget build(BuildContext context) {
    return LoginValidation(
      routeIfNotLoggedIn: "/myLoginRoute",
      child: MyAwesomePage(),
    );
  }
于 2020-11-28T04:59:28.037 回答