我对提供程序架构有什么误解?
我的入口点:
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<AuthProvider>(
create: (context) => AuthProvider()),
ChangeNotifierProvider<UserProvider>(
create: (context) => UserProvider()),
],
child: BdopsApp(),
),
);
}
class BdopsApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.teal,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
initialRoute: LoginView.routeName,
routes: {
HomepageView.routeName: (context) => HomepageView(),
LoginView.routeName: (context) => LoginView(),
},
);
}
}
首先,我使用我的登录凭据登录。
class LoginView extends StatelessWidget {
static const routeName = 'LoginView';
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final User _user = User();
@override
Widget build(BuildContext context) {
return Consumer<AuthProvider>(
builder: (_, data, __) => Scaffold(
appBar: CustomAppBar.getAppBar(
title: 'BDOPS',
subTitle: 'LOG IN',
),
drawer: SidveNavDrawer(),
body: Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
FormInputTextBox(
labelText: 'Email',
hintText: 'example@domain.com',
validator: (value) {
if (value == null) {
return 'Login email not provided';
}
if (!RegExp(xEmailRegx).hasMatch(value)) {
return 'Not a valid email address';
}
},
onSaved: (value) {
_user.email = value.trim();
},
),
FormInputTextBox(
labelText: 'Password',
hintText: '* * * * *',
isPassword: true,
validator: (value) {
if (value == null) {
return 'Login password not provided';
}
if (value.toString().length < 6) {
return 'Minmum length is six charector';
}
},
onSaved: (value) {
_user.password = value.trim();
},
),
Divider(
height: 30.0,
),
RaisedButton(
color: Colors.deepOrange,
padding: EdgeInsets.symmetric(vertical: 10.0),
onPressed: () async {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
var res = await data.loginUser(_user);
if (res == true) {
AlertDialog(
title: Text('Login Success'),
);
} else {
AlertDialog(
title: Text('Login Failed'),
);
}
Navigator.pushReplacementNamed(
context, HomepageView.routeName);
},
child: Text(
'SUBMIT',
style: xHeaderText,
),
),
],
),
),
),
),
);
}
}
然后我导航到主页,在页面加载时,屏幕应该从 AuthUser Provider 的 getAuthUser 中获取 Auth 用户,并自触发一个方法,使用 userID 从 API 获取登录用户的详细信息。
class HomepageView extends StatelessWidget {
static const routeName = 'HomePageView';
@override
Widget build(BuildContext context) {
final userId = Provider.of<AuthProvider>(context).getAuthUser.id;
return Consumer<UserProvider>(
builder: (_, dataProvider, __) {
dataProvider.fetchAUser(userId);
return Scaffold(
appBar: CustomAppBar.getAppBar(title: 'BDOPS', subTitle: 'Home'),
drawer: SidveNavDrawer(),
body: Text(dataProvider.getSingelUser.email),
);
},
);
}
}
这样做,我的应用程序首先抛出一个错误,然后一遍又一遍地重建和调用 API。
我的提供者课程是:
class AuthProvider with ChangeNotifier {
User _authUser;
String _errorMessage;
AuthTokens _tokens;
Future<bool> loginUser(User user) async {
if (user.email == null || user.password == null) {
_setErrorMessage('Provide login credentials');
}
var resp = await APIService().loginUser(
email: user.email,
password: user.password,
);
if (resp.statusCode == 200) {
_setAuthToken(authTokensFromJson(resp.body));
var userFetched =
await UserProvider().fetchAUser(decodeJwt(_tokens.access)['user_id']);
if (userFetched != null) {
_setAuthUser(userFetched);
return true;
}
}
_setErrorMessage('Failed to login');
return false;
}
void _setAuthToken(value) {
_tokens = value;
}
void _setAuthUser(value) {
_authUser = value;
notifyListeners();
}
User get getAuthUser {
return _authUser;
}
void _setErrorMessage(value) {
_errorMessage = value;
notifyListeners();
}
String get getErrorMessage {
return _errorMessage;
}
}
class UserProvider with ChangeNotifier {
User _user;
Future<User> fetchAUser(userId) async {
var response = await APIService().getAUser(userId: userId);
if (response.statusCode == 200) {
setUser(userFromJson(response.body));
print('Called from UserProvider');
return _user;
}
return null;
}
void setUser(value) {
_user = value;
notifyListeners();
}
User get getSingelUser {
return _user;
}
}