我從顫振應用程式中得到了奇怪的行為,試圖解決這個問題兩天......
- 如果我嘗試在熱重啟后立即提交登錄表單(空欄位)-> 錯誤:欄位為空-> 然后我填寫表單,我將嘗試再次重新提交,一切正常。
- 如果我進行熱重啟并填寫登錄表單而沒有事先提交空表單,則提交按鈕將永遠不會將資料發送到服務器。由于現有的 EventSink 錯誤,由于某種原因在第一種情況下沒有出現。
這是代碼:表單小部件:
@override
Widget build(BuildContext context) {
final FormBloc formBloc = FormProvider.of(context);
Widget _emailField(FormBloc formBloc) {
return StreamBuilder(
stream: formBloc.email,
builder: (context, AsyncSnapshot<String> snapshot) {
return TextFormField(
autofocus: false,
keyboardType: TextInputType.emailAddress,
onChanged: formBloc.changeEmail,
Widget _passwordField(FormBloc formBloc) {
return StreamBuilder(
stream: formBloc.password,
builder: (context, AsyncSnapshot<String> snapshot) {
return TextFormField(
autofocus: false,
obscureText: !_passwordVisible,
keyboardType: TextInputType.text,
onChanged: formBloc.changePassword,
表格塊:
class FormBloc with LoginValidationMixin {
final _email = BehaviorSubject<String>();
final _password = BehaviorSubject<String>();
final _errorMessage = BehaviorSubject<String>();
// getters
Function(String) get changeEmail => _email.sink.add;
Function(String) get changePassword => _password.sink.add;
Function(String) get addError => _errorMessage.sink.add;
// streams
Stream<String> get email => _email.stream.transform(validatorEmail);
Stream<String> get password => _password.stream.transform(validatorPassword);
Stream<String> get errorMessage => _errorMessage.stream;
Stream<bool> get submitValidForm => Rx.combineLatest3(
email,
password,
errorMessage,
(e, p, er) => true,
);
late AuthService authInfo;
// login
dynamic login(BuildContext context) async {
authInfo = AuthService();
final email = _email.valueOrNull;
final password = _password.valueOrNull;
if (email == null || password == null) {
addError("Password or Email cannot be empty");
return;
}
final response =
await authInfo.login(email, password, this);
if (response == null) {return;}
final data = jsonDecode(response) as Map<String, dynamic>;
if (data['status_code'] != 200) {
} else {
final tokens = data['tokens'];
AuthService.setToken(
tokens["access"], tokens["refresh"], data['client_id']);
Navigator.pushNamed(context, '/home');
return data;
}
}
驗證
class LoginValidationMixin {
static String get passwordPattern => "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}";
final validatorEmail = StreamTransformer<String, String>.fromHandlers(
handleData: (email, sink) {
sink.add(email);
if (!EmailValidator.validate(email)) {
sink.addError('Email should look like:'
'[email protected]\n');
} else {
sink.add(email);
}
},
);
final validatorPassword = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink) {
sink.add(password);
if (!RegExp(passwordPattern).hasMatch(password)) {
sink.addError('A hint, password should contain\n'
'at least 8 characters\n'
'at least 1 upper case character\n'
'at least 1 upper case character\n'
'at least 1 numerical character\n');
} else {
sink.add(password);
}
},
);
}
登錄按鈕
Widget _loginButton(FormBloc formBloc) {
return StreamBuilder<bool>(
stream: formBloc.submitValidForm,
builder: (context, AsyncSnapshot<bool> snapshot) {
return Material(
child: MaterialButton(
onPressed: () {
if (snapshot.error != null) {
print(snapshot.error) <<<< in the second scenario, here is always an error, even if filed validations have passed. While in the first scenario, this does work as expected.
return;
} else {
formBloc.login(context);
}
},
因此,在第二種情況下,EventSink 始終保持錯誤,并且按鈕基本上不可點擊。但是,在第一種情況下,EventSink 作業正常,如果有錯誤則保存錯誤,如果添加了正確的值則清除它們。我該怎么辦?有沒有辦法清除 EventSink 錯誤?
uj5u.com熱心網友回復:
所以這就是我解決此案的方式,首先我意識到流只會產生價值而不是存盤。
pskink:EvenSink 沒有錯誤接下來,我檢查了
Stream<bool> get submitValidForm => Rx.combineLatest3(
email,
password,
errorMessage, <<< this one is null in the case two, therefore my solution was to give it an initial value while handling email or password.
(e, p, er) => true,
);
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/415987.html
標籤:
