所以我有一个登录页面,用户在其中输入用户名和密码,代码如下:
class LoginPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
_ViewModel _viewModel;
TextEditingController _usernameController;
TextEditingController _passwordController;
@override
void initState() {
super.initState();
_usernameController = TextEditingController();
_passwordController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, _ViewModel>(
converter: (store) => _ViewModel.fromStore(store),
builder: (context, viewModel) {
_viewModel = viewModel;
return Scaffold(
resizeToAvoidBottomPadding: false,
body: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: 40.0,
left: 16.0,
right: 16.0,
),
child: PrimaryTextField(
controller: _usernameController,
hintText: "Username",
),
),
Padding(
padding: EdgeInsets.only(
top: 40.0,
left: 16.0,
right: 16.0,
),
child: PrimaryTextField(
controller: _passwordController,
hintText: "Password",
obsecureText: true,
),
),
Container(
margin: EdgeInsets.only(top: 40.0),
child: _getLoginButtonOrProgress(),
),
],
),
);
},
);
}
_getLoginButtonOrProgress() {
return _viewModel.loadingData.status == LoadingStatus.LOADING
? PrimaryCircularProgress(
progressColor: Colors.blue,
)
: PrimaryButton(
text: "Login",
onPressed: () {
print('Clicking');
print(_usernameController.text);
print(_passwordController.text);
_viewModel.onLoginPressed(
username: _usernameController.text,
password: _passwordController.text,
);
},
);
}
}
class _ViewModel {
final LoadingData loadingData;
final Function({String username, String password}) onLoginPressed;
_ViewModel({
this.loadingData,
this.onLoginPressed,
});
factory _ViewModel.fromStore(Store<AppState> store) {
return _ViewModel(
loadingData: store.state.loginState.loadingData,
onLoginPressed: ({String username, String password}) {
store.dispatch(LoginAction(username: username, password: password));
},
);
}
}
按下按钮时,将调度LoginAction
,中间件将发送http请求,而在收到请求时,将调度LoginResponse
。
我面临的问题是收到登录结果后如何显示Snackbar
。 Snacker
在构建期间不会进入窗口小部件树,请显示当应用程序状态更改时,我可以在窗口小部件树中进行某些操作(构建后)。
登录中间件:
class LoginMiddleware extends MiddlewareClass<AppState> {
Repository repository;
LoginMiddleware({
this.repository,
});
@override
void call(Store<AppState> store, action, NextDispatcher next) {
if (action is LoginAction) {
_sendLoginRequest(action, next);
}
}
_sendLoginRequest(LoginAction action, NextDispatcher next) async {
next(action);
var result = await repository.login(
username: action.username, password: action.password);
var responseAction;
if (result.status == Status.SUCCESS) {
responseAction = LoginResponseAction(isSuccessful: true);
} else {
responseAction = LoginResponseAction(isSuccessful: false);
}
next(responseAction);
}
}