[英]How can i access to a variable in main.dart to other pages in flutter, i am using Getx state management
[英]Why my observable variable can not update the "main.dart" in Flutter using GetX?
以下代碼是我的auth_controller.dart
代碼。 我看到response
來自后端工作,這是預期的,我有token
,並且在我提交表單后isAuth
值更改為true
:
enum AuthMode { Signup, Login }
class AuthController extends GetxController
with GetSingleTickerProviderStateMixin {
static AuthController instance = Get.find();
Rx<dynamic>? authMode = AuthMode.Login.obs;
RxBool? isLoading = false.obs;
String? _token;
DateTime? _expiryDate;
String? _userId;
Timer? _authTimer;
final _isAuth = false.obs;
AnimationController? controller;
Animation<Offset>? slideAnimation;
Animation<double>? opacityAnimation;
// late TextEditingController passwordController;
// final key = GlobalKey<FormState>();
@override
void onInit() {
super.onInit();
controller = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 300,
),
);
slideAnimation = Tween<Offset>(
begin: const Offset(0, -1.5),
end: const Offset(0, 0),
).animate(
CurvedAnimation(
parent: controller as Animation<double>,
curve: Curves.fastOutSlowIn,
),
);
opacityAnimation = Tween(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: controller as Animation<double>,
curve: Curves.easeIn,
),
);
// _heightAnimation.addListener(() => setState(() {}));
// passwordController = TextEditingController();
}
@override
void onClose() {
super.onClose();
// passwordController.dispose();
}
bool get isAuth {
_isAuth.value = token != null;
return _isAuth.value;
}
String? get token {
if (_expiryDate != null &&
_expiryDate!.isAfter(DateTime.now()) &&
_token != null) {
return _token;
}
return null;
}
String? get userId {
return _userId;
}
Future<void> _authenticate(
String email, String password, String urlSegment) async {
// print('app is here!!!5555');
final host = UniversalPlatform.isAndroid ? '10.0.2.2' : '127.0.0.1';
final url = Uri.parse('http://$host:8000/api/$urlSegment');
//final url = Uri.parse('http://10.0.2.2:8000/api/$urlSegment');
//final url = Uri.parse('http://127.0.0.1:8000/api/$urlSegment');
try {
final http.Response response = await http.post(
url,
headers: {"Content-Type": "application/json"},
body: json.encode(
{
'email': email,
'password': password,
//'returnSecureToken': true,
},
),
);
print('this is responsde ');
print(json.decode(response.body));
final responseData = json.decode(response.body);
if (responseData['error'] != null) {
throw HttpException(responseData['error']['message']);
} else {
_token = responseData['idToken'];
_userId = responseData['id'];
_expiryDate = DateTime.now().add(
Duration(
seconds: responseData['expiresIn'],
),
);
}
_autoLogout();
// update();
final prefs = await SharedPreferences.getInstance();
final userData = json.encode(
{
'token': _token,
'userId': _userId,
'expiryDate': _expiryDate!.toIso8601String(),
},
);
prefs.setString('userData', userData);
// print(prefs.getString('userData'));
} catch (error) {
throw error;
}
}
Future<void> signup(String email, String password) async {
return _authenticate(email, password, 'signup');
}
Future<void> login(String email, String password) async {
return _authenticate(email, password, 'login');
}
Future<bool> tryAutoLogin() async {
final prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey('userData')) {
return false;
}
final Map<String, Object> extractedUserData = Map<String, Object>.from(
json.decode(prefs.getString('userData') as String));
final expiryDate =
DateTime.parse(extractedUserData['expiryDate'] as String);
if (expiryDate.isBefore(DateTime.now())) {
return false;
}
_token = extractedUserData['token'] as String;
_userId = extractedUserData['userId'] as String;
_expiryDate = expiryDate;
// update();
_autoLogout();
return true;
}
Future<void> logout() async {
_token = null;
_userId = null;
_expiryDate = null;
if (_authTimer != null) {
_authTimer!.cancel();
_authTimer = null;
}
// update();
final prefs = await SharedPreferences.getInstance();
// prefs.remove('userData');
prefs.clear();
}
void _autoLogout() {
if (_authTimer != null) {
_authTimer!.cancel();
}
final timeToExpiry = _expiryDate!.difference(DateTime.now()).inSeconds;
_authTimer = Timer(Duration(seconds: timeToExpiry), logout);
}
}
但它仍然會堅持身份驗證頁面,並且不會 go 到我在main.dart
文件中定義的主頁:
void main() {
Get.put(MenuController());
Get.put(NavigationController());
Get.put(AuthController());
Get.put(AuthCard);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Obx(() => GetMaterialApp(
initialRoute: AuthController.instance.isAuth
? homeScreenRoute
: authenticationScreenRoute,
unknownRoute: GetPage(
name: '/not-found',
page: () => PageNotFound(),
transition: Transition.fadeIn),
getPages: [
GetPage(
name: rootRoute,
page: () {
return SiteLayout();
}),
GetPage(
name: authenticationScreenRoute,
page: () => const AuthenticationScreen()),
GetPage(name: homeScreenRoute, page: () => const HomeScreen()),
],
debugShowCheckedModeBanner: false,
title: 'BasicCode',
theme: ThemeData(
scaffoldBackgroundColor: light,
textTheme: GoogleFonts.mulishTextTheme(Theme.of(context).textTheme)
.apply(bodyColor: Colors.black),
pageTransitionsTheme: const PageTransitionsTheme(builders: {
TargetPlatform.iOS: FadeUpwardsPageTransitionsBuilder(),
TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
}),
primarySwatch: Colors.blue,
),
));
}
}
有什么問題,我該如何解決?
初始路由僅在應用程序啟動時設置一次,並且根據您顯示的內容, isAuth
將始終在GetMaterialApp
構建時返回 false。
將整個應用程序包裝在Obx
中不會觸發基於您為初始路線設置的導航。 當您運行任何登錄嘗試時,它已經過去了。
成功登錄后,您需要手動導航到主屏幕。
Instead I suggest checking for a non null token from storage before the app starts and if its null, go to your auth page and if not, go to your home page. 兩者都不需要Obx
周圍的GetMaterialApp
,因為您需要正確初始化_isAuth
並在runApp()
之前await
它。
我可以通過在我的main.dart
文件中添加以下行來簡單地解決問題:
home: Obx(() => AuthController.instance.isAuth
? const HomeScreen()
: const AuthenticationScreen()),
並刪除以下內容:
initialRoute
: AuthController.instance.isAuth
? homeScreenRoute
: authenticationScreenRoute,
我還在GetMaterialApp()
之前刪除了Obx
。
新的main.dart
看起來像這樣:
void main() {
Get.put(MenuController());
Get.put(NavigationController());
Get.put(AuthController());
Get.put(AuthCard);
AuthController.instance.isAuth ? runApp(MyApp()) : runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
unknownRoute: GetPage(
name: '/not-found',
page: () => PageNotFound(),
transition: Transition.fadeIn),
getPages: [
GetPage(
name: rootRoute,
page: () {
return SiteLayout();
}),
GetPage(
name: authenticationScreenRoute,
page: () => const AuthenticationScreen()),
GetPage(name: homeScreenRoute, page: () => const HomeScreen()),
],
debugShowCheckedModeBanner: false,
title: 'BasicCode',
theme: ThemeData(
scaffoldBackgroundColor: light,
textTheme: GoogleFonts.mulishTextTheme(Theme.of(context).textTheme)
.apply(bodyColor: Colors.black),
pageTransitionsTheme: const PageTransitionsTheme(builders: {
TargetPlatform.iOS: FadeUpwardsPageTransitionsBuilder(),
TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
}),
primarySwatch: Colors.blue,
),
home: Obx(() => AuthController.instance.isAuth
? const HomeScreen()
: const AuthenticationScreen()),
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.