我正在使用
provider
创建一个名为 GlobalsProvider
的类,它包含一些全局变量。它需要保存用户当前的登录状态,因此要做到这一点,我需要两件事:一个用于 loggedIn
的全局布尔变量和一个调用 SQL Server 存储过程以查看用户的登录状态是否仍然存在的流。有效。
现在我正在模拟一个“流”,只需让 flutter 每 10 秒调用一次来获取登录状态。我能够通过在
login.dart
中运行流来使其工作 - 它在那里工作得很好。但是,我希望该流是全局的,所以我想将其移至GlobalsProvider
。这样,如果登录状态的流突然说不再允许用户登录,我可以关闭用户正在使用的任何小部件,返回到登录屏幕,并阻止用户能够在未登录的情况下点击后退按钮返回并继续工作。
现在我的流只运行一次,但它应该每 10 秒触发一次。我知道它不起作用,因为我没有每 10 秒收到一次打印语句。
全球提供商:
Timer? timer;
void startLoginStream(/*...parms...*/) {
timer = Timer.periodic(const Duration(seconds: 10), (Timer t) => loginStream(/*...parms...*/);
notifyListeners();
}
void loginStream(/*...parms...*/) async {
final previousLoggedIn = loggedIn;
await sqlConnect(/*...parms...*/);
var res = await SqlConn.readData("exec spHandheldLogin");
res = json.decode(res);
res = res[0]; //Gets the first object in the list. This is fine because this SP will only ever return 1 row
var loginState = res['LoginState'];
if (kDebugMode) {print('${StaticGlobals.tagATS} loginStream loginState: ${loginState.toString()}');}
if (loginState == 1) {
loggedIn = true;
loggedInUser = username;
} else {
loggedIn = false;
loggedInUser = '';
}
await sqlDisconnect();
//Only need to update the listeners if the login state changes
if (loggedIn != previousLoggedIn) {
notifyListeners();
}
}
登录.dart:
@override
Widget build(BuildContext context) {
return Consumer<GlobalsProvider>(
builder: (context, value, child) => Scaffold(appBar: AppBar(
title: const Text('Login'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: TextButton(
onPressed: () async {
final status = await value.login(/*...parms...*/);
if (value.loggedIn == true) { //If login was successful, start the "stream"
value.loginStream(/*...parms...*/);
} else {
Fluttertoast.showToast(
msg: "ERROR",
toastLength: Toast.LENGTH_LONG,
);
}
},
child: const Text('Submit'),
),
)
//...
wrapper.dart:
class Wrapper extends StatelessWidget {
const Wrapper({super.key});
@override
Widget build(BuildContext context) {
return Consumer<GlobalsProvider>(builder: (context, value, child) {
if (value.loggedIn == true) {
return const Forms(); //widget #2
} else {
return const Login(); //widget #1
}
});
}
}
问题出在我按下按钮时调用了错误的函数。当我应该做
value.loginStream
时,我却在做value.startLoginStream
。这两个函数都存在,所以这就是我没有收到错误的原因。