gpt4 book ai didi

dart - StreamBuilder TextField 在其他地方更改时不会更新其值

转载 作者:行者123 更新时间:2023-12-03 03:01:49 26 4
gpt4 key购买 nike

我有一个遵循 BLOC 模式的响应式(Reactive)登录表单。我正在尝试以编程方式清除其中的所有值。在我的 Bloc 中,我的提交函数将空字符串传递给我的流接收器:

class Bloc with Validators {
final _email = BehaviorSubject<String>();
final _password = BehaviorSubject<String>();

Stream<String> get email => _email.stream.transform(validateEmail);
Stream<String> get password => _password.stream.transform(validatePassword);
Stream<bool> get submitValid => Observable.combineLatest2(email, password, (String e, String p) {
var valid = (e != null && e.isNotEmpty)
&& (p != null && p.isNotEmpty);
print('$e && $p = $valid');
return valid;
});

Function(String) get changeEmail => _email.sink.add;
Function(String) get changePassword => _password.sink.add;

submit() {
final validEmail = _email.value;
final validPassword = _email.value;
print('final values: $validEmail && $validPassword');
changeEmail('');
changePassword('');
}

dispose() {
_email.close();
_password.close();
}
}

当我按下调用此 submit() 的提交按钮时函数,我收到两个文本字段的错误消息,因为电子邮件和密码的值在幕后发生了变化,但它们在 TextFields 中没有视觉更新。这是我的 TextFields 和提交按钮的 StreamBuilders:
Widget emailField(Bloc bloc) {
return StreamBuilder(
stream: bloc.email,
builder: (context, snapshot) { // re-runs build function every time the stream emits a new value
return TextField(
onChanged: bloc.changeEmail,
autocorrect: false,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
icon: Icon(Icons.email),
hintText: 'email address (you@example.com)',
labelText: 'Email',
errorText: snapshot.error
)
);
}
);
}

Widget passwordField(Bloc bloc) {
return StreamBuilder(
stream: bloc.password,
builder: (context, AsyncSnapshot<String> snapshot) {
return TextField(
onChanged: bloc.changePassword,
autocorrect: false,
obscureText: true,
decoration: InputDecoration(
icon: Icon(Icons.security),
hintText: 'must be greater than 6 characters',
labelText: 'Password',
errorText: snapshot.error
)
);
}
);
}

Widget submitButton(Bloc bloc) {
return StreamBuilder(
stream: bloc.submitValid,
builder: (context, snapshot) {
return RaisedButton(
child: Text('Logins'),
color: Colors.blue,
onPressed: !snapshot.hasData || snapshot.hasError || snapshot.data == false
? null
: bloc.submit
);
}
);
}'

这是我在 Bloc 中用于验证器的代码:
class Validators {
final validateEmail = StreamTransformer<String, String>.fromHandlers(
handleData: (email, sink) {
RegExp exp = new RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+");
var valid = exp.hasMatch(email);
if (valid) {
sink.add(email);
} else {
sink.add('');
sink.addError('Invalid email address!');
}
}
);

final validatePassword = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink) {
var valid = password.length >= 6;
if (valid) {
sink.add(password);
} else {
sink.add('');
sink.addError('Password must be at least 6 characters long!');
}
}
);
}

在我的验证器中,每当出现错误时,我都会发出一个空字符串。这使得 submitValid getter 在用户使曾经有效的内容无效时起作用。

最佳答案

我知道这已经很长时间了,但这是我解决它的方法。

首先,我创建了一个 TextEditingController对于我的TextField .然后我在 BLoC 上创建了两个方法:updateTextOnChangedupdateTextElsewhere .在第一个我刚刚检索到的值(因为我需要它稍后使用)。在第二个中,我添加了一个接收器来更新 TextField 上的 Controller 。

小部件:

  return StreamBuilder<String>(
stream: bloc.streamText,
builder: (context, snapshot) {
_controller.text = snapshot.data;
return Expanded(
child: TextField(
controller: _controller,
onChanged: (value) => {bloc.updateTextOnChanged(value)},
),
);
}
);

集团:
  Stream<String> get streamText => _controllerTxt.stream;
String _myText;

void updateTextElsewhere(String value) {
_controllerTxt.sink.add(value);
}

void updateTextOnChanged(String value) {
_myText = value;
}

那么您只需调用 updateTextElsewhere()每当您需要在 onChanged 之外对其进行更新时。

在您的情况下,只需添加一个空字符串,例如: updateTextElsewhere("");

关于dart - StreamBuilder TextField 在其他地方更改时不会更新其值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55621651/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com