已解决:Flutter Provider:改变屏幕上的数据消失

SOLVED: Flutter Provider: Disappearing data on changing screen

我用过几次 flutter 'provider' 包都没有问题,但现在我遇到了问题。

登录时,我从 Firebase 数据库获取用户角色,并通过 [=49= 更改我的 UserProvider class(由 ChangeNotifier 扩展)的 'role' 属性 ] 函数。

在导航到主屏幕时,我尝试使用 'getRole' 函数从 UserProvider 获取值,但它是一个空字符串。不知何故,改变屏幕我失去了价值。

我试过在更改角色和获取时打印值,我可以确认我更改了值,但不知何故在更改屏幕后它丢失了。

代码的相关部分如下:

user_provider.dart

import 'package:flutter/cupertino.dart';

class UserProvider with ChangeNotifier {
  String _role = '';
  

  void changeRole(String newRole) {
    _role = newRole;
    print('CHANGEROLE: $_role'); // print statements added just for trying to solve this problem
    notifyListeners();
  }

  String get getRole {
    print('GETROLE: $_role');
    return _role;
  }
}

main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(
    ChangeNotifierProvider(
      create: (context) => UserProvider(),
      child: MyApp(),
    ),
  );
}

...

服务上的登录功能

  void login() async {
    try {
      UserCredential userCredential = await FirebaseAuth.instance
          .signInWithEmailAndPassword(email: email, password: password);

      var data = await FirebaseFirestore.instance.collection('users').where('uid', isEqualTo: userCredential.user.uid).get();
      UserProvider().changeRole(data.docs[0]['role']);

      Navigator.of(context).pushNamed(MainScreen.routeName);

...

这里是它应该显示的地方: main_screen.dart

...
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Consumer<UserProvider>(
              builder: (context, user, child) {
                return Text('This is your role: ${user.getRole}');
              },
            ),
...

尽管如此,我得到一个空字符串,因为它没有被更改。 UserProvider 模型上的打印确认:

I/flutter (23760): CHANGEROLE: megauser
I/flutter (23760): GETROLE:

如您所见,我正在更改角色,但 getter returns 是一个空字符串。我做错了什么?

编辑:感谢 Sifat Amin 指出解决方案。只需将“_role”参数设置为 'static' 即可。

像这样创建您的应用程序

MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) => UserProvider()),
      ],
      child: MyApp(),
    ),
  );

添加此行并运行您的 UserProvider class

String get role => _role;

void changeRole(String newRole){
   _role = newRole;
   notifyListeners();
}

并像这样更改登录屏幕中的角色

context.read<UserProvider>().changeRole(newRole);

并在所有小部件中像这样访问它

context.read<UserProvider>().role;

我想将 _role 更改为静态就足够了。由于您每次都在创建一个新实例,因此数据会丢失。将 _role 声明为静态就足够了

static String role ;

所以你根本不需要 get 方法。我认为它应该有效