提供程序不更新Flutter中的数据 [英] Provider dont update a data in Flutter

查看:105
本文介绍了提供程序不更新Flutter中的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Flutter上创建一个项目.我正在使用提供程序来更改应用程序中的屏幕.这是我的main.dart文件:

I'm create a project on Flutter. And I'm using a provider to change screens in my app. Here is my main.dart file:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:school_app/services/auth_service.dart';
import 'package:school_app/wrapper.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => AuthService().auth,
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}

这也是我的wrapper.dart文件,屏幕在其中选择:

Also this is my wrapper.dart file where the screens choose:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:school_app/screens/authenticate/auth.dart';
import 'package:school_app/models/user.dart';
import 'package:school_app/screens/school/home.dart';
import 'package:school_app/services/auth_service.dart';

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<AuthProvider>(context); 
    print(user.auth);
    if(!user.auth) return Auth();
    return Home();
  }
}

这是我的AuthProvider类:

And it is my AuthProvider class:

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

class AuthService {


   /* AuthUser _user(User user) {
    return user != null ? AuthUser(uid: user.uid) : null;
  }*/

AuthProvider auth = new AuthProvider();

  //sign in
  Future signIn(String username, String password) async {
    try {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      var dio = Dio();
      Response user = await dio.post('url', data: {
        'username': username,
        'password': password
      });
      if(user.data['success'] == false) return user.data['msg'];
      await prefs.setString('token', user.data['token']);
      auth.setAuth(true);
      print("SUCCESS");
    } catch(e) {
      print('Error ' + e.toString());
    }
  }

}

class AuthProvider with ChangeNotifier {
  bool _auth;

  AuthProvider() {
    _auth = false;
  }

  bool get auth => _auth;

  void setAuth(bool auth) {
    _auth = auth;
    notifyListeners();
  }
}

当我在AuthProvider类setAuth中调用一个函数时,没有任何改变.您能帮我发现我的错误吗?

And when I call a function in AuthProvider class setAuth, nothing changed. Can you help me and find my mistake?

编辑

我正在进行您编写的所有更改,但是没有用.这是我的main.dart:

I'm making all changes that you writes but it is not working. Here is my main.dart:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:school_app/services/auth_service.dart';
import 'package:school_app/wrapper.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => AuthProvider(),
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}

还包括wrapper.dart:

Also wrapper.dart:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:school_app/screens/authenticate/auth.dart';
import 'package:school_app/screens/school/home.dart';
import 'package:school_app/services/auth_service.dart';

class Wrapper extends StatefulWidget {
  @override
  _WrapperState createState() => _WrapperState();
}

class _WrapperState extends State<Wrapper> {

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    AuthService().auth;
  }

  @override
  Widget build(BuildContext context) {
    return Consumer<AuthProvider>(builder: (context, authProvider, child) {
      print(authProvider.auth);
      if (!authProvider.auth) {
        return Auth();
      } else {
        return Home();
      }
    });
  }
}

以及AuthService和AuthProvider类:

And AuthService and AuthProvider classes:

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

class AuthService {


   /* AuthUser _user(User user) {
    return user != null ? AuthUser(uid: user.uid) : null;
  }*/

AuthProvider auth = new AuthProvider();

  //sign in
  Future signIn(String username, String password) async {
    try {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      var dio = Dio();
      Response user = await dio.post('url', data: {
        'username': username,
        'password': password
      });
      if(user.data['success'] == false) return user.data['msg'];
      await prefs.setString('token', user.data['token']);
      auth.setAuth(true);
      print("SUCCESS");
    } catch(e) {
      print('Error ' + e.toString());
    }
  }

}

class AuthProvider with ChangeNotifier {
  bool _auth;

  AuthProvider() {
    _auth = false;
  }

  bool get auth => _auth;

  void setAuth(bool auth) {
    _auth = auth;
    notifyListeners();
  }
}

注意,这里有两个类,在AuthService中,我正在调用函数.setAuth(true).

Notice, that here two classes and in AuthService I'm calling function .setAuth(true).

推荐答案

这里唯一缺少的部分是您从不使用AuthProvider来监听 notifyListeners()触发器.
正确的实现如下所示(我没有尝试过,您可能需要纠正一些错字错误,但是您会明白的!)

The only missing part here is that you never Consume the AuthProvider to listen to the notifyListeners() trigger.
The correct implementation looks like the following (I didn't try it, you may have to correct some typo errors, but you'll get the idea !)

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<AuthProvider>(
        builder: (context, authProvider, child) {
          if (!authProvider.auth) {
            return Auth();
          } else {
            return Home();
          }
        }

    );
  }
}

编辑
我没有注意到您没有在ChangeNotifierProvider中注入正确的类.您还必须更新您的窗口小部件MyApp

EDIT
I didn't notice you weren't injecting the right Class in your ChangeNotifierProvider. You'll also have to update your widget MyApp

@override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => AuthProvider(),
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }

在这种情况下,您可能应该将 Wrapper 小部件转换为有状态小部件,并且在 initState 方法中,应调用 AuthService().auth .

And in this case you probably should transform your Wrapper widget to a Stateful widget, and in the initState method you should call AuthService().auth.

我强烈建议您阅读提供商的官方文档,看起来情况并非一帆风顺清晰而又头脑清晰

I strongly recommend you to read the official documentation of Provider, looks like things aren't crystal clear yet in your mind

编辑2
您仍然缺少提供程序库的要点.

EDIT 2
You're still missing the point of the Provider library.

该库的目标是向您的窗口小部件树提供类的实例,这样您就不必在每个窗口小部件中重新创建实例.

The goal of this lib is to provide an instance of a class to your widget tree so you don't have to re-create an instance in each widget.

在这里,在 AuthService 类中,您将使用 AuthProvider auth = new AuthProvider(); 重新创建AuthProvider,而不是引用父级中创建的现有实例.小部件.

Here, in AuthService class you're re-creating a AuthProvider with AuthProvider auth = new AuthProvider(); instead of referring to the existing instance created in the parent Widget.

要引用以前创建的实例,您应该在AuthService类中使用 Provider.of< AuthProvider>(context); ;或者甚至更好的是,将AuthProvider的实例作为参数传递给signIn方法.

To refer to a previously created instance, you should use Provider.of<AuthProvider>(context); in the AuthService class, or, even better, pass the instance of AuthProvider as a parameter in the signIn method.

这篇关于提供程序不更新Flutter中的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆