gpt4 book ai didi

google-app-engine - Rx.combineLatest2无法正常工作

转载 作者:行者123 更新时间:2023-12-03 04:24:25 32 4
gpt4 key购买 nike

我是使用 flutter 的新手。我试图在flutter中创建一些示例应用程序以创建自己的应用程序。我发现了带有团块模式的 flutter 打中很好的应用程序。请参阅以下 link

这只是一个登录页面。表单中有一个带有验证的电子邮件和密码文本框。一个验证器用于电子邮件,另一个验证器用于密码长度。表单中有一个提交按钮,最初已禁用,如果电子邮件和密码成功验证,则启用提交按钮。它使用带有 rxdart 软件包的块模式架构。

我在提交按钮验证方面遇到问题,在输入电子邮件和密码字段后,未启用按钮字段。

按钮验证码

Stream<bool> get submitCheck => 
Rx.combineLatest2(email, password, (e, p) => true);

请参见下面的代码。

main.dart
import 'package:bloc_login/pagetwo.dart';
import 'package:flutter/material.dart';
import 'package:bloc_login/bloc.dart';
import 'package:flutter/rendering.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.teal,
),
debugShowCheckedModeBanner: false,
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
changethePage(BuildContext context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => PageTwo()));
}

@override
Widget build(BuildContext context) {
final bloc = Bloc();

return Scaffold(
appBar: AppBar(
title: Text("Bloc pattern"),
),
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
StreamBuilder<String>(
stream: bloc.email,
builder: (context, snapshot) => TextField(
onChanged: bloc.emailChanged,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Enter Email",
labelText: "Email",
errorText: snapshot.error),
),
),
SizedBox(
height: 20,
),
StreamBuilder<String>(
stream: bloc.password,
builder: (context, snapshot) => TextField(
onChanged: bloc.passwordChanged,
keyboardType: TextInputType.text,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Enter password",
labelText: "Password",
errorText: snapshot.error),
),
),
SizedBox(
height: 20,
),
StreamBuilder<bool>(
stream: bloc.submitCheck,
builder: (context, snapshot) => RaisedButton(
color: Colors.tealAccent,
onPressed: (snapshot.data != null)
? () => changethePage(context)
: null,
child: Text("Submit"),
))
],
),
),
),
);
}
}

bloc.dart
import 'dart:async';
import 'package:bloc_login/validator.dart';
import 'package:rxdart/rxdart.dart';

class Bloc extends Object with Validators implements BaseBloc {
final _emailController = StreamController<String>();
final _passwordController = StreamController<String>();

Function(String) get emailChanged => _emailController.sink.add;
Function(String) get passwordChanged => _passwordController.sink.add;

Stream<String> get email => _emailController.stream.transform(emailValidator);
Stream<String> get password =>
_passwordController.stream.transform(passwordValidator);

Stream<bool> get submitCheck =>
Rx.combineLatest2(email, password, (e, p) => true);

@override
void dispose() {
_emailController.close();
_passwordController.close();
}
}

abstract class BaseBloc {
void dispose();
}

validator.dart
import 'dart:async';

mixin Validators {
var emailValidator =
StreamTransformer<String, String>.fromHandlers(handleData: (email, sink) {
if (email.contains("@")) {
sink.add(email);
} else {
sink.addError("Email is not valid.");
}
});

var passwordValidator = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink) {
if (password.length > 4) {
sink.add(password);
} else {
sink.addError("Password length should be greater than 4.");
}
});
}

请指教。

最佳答案

Combinelatest2很好,问题是您在每次重建中都创建了一个新的块。

因此,请在initState方法中创建块,并在StatefulWidgetdispose方法中处理该块。

而且您的StreamController的Stream仅支持一个订阅者,因此,如果您希望StreamStreamController可以被监听多次,则需要将其作为广播流,其中一种方法是使用StreamController .broadcast ()构造函数。

P.D.如果使用bloc模式创建表单,则可以检查flutter_form_bloc,它可以节省大量代码。

从Dart 2.1 you don't need to extend an object to use a mixin开始

class Bloc with Validators implements BaseBloc {
final _emailController = StreamController<String>.broadcast();
final _passwordController = StreamController<String>.broadcast();
//...
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
Bloc _bloc;

@override
void initState() {
super.initState();
_bloc = Bloc();
}

@override
void dispose() {
_bloc.dispose();
super.dispose();
}

changethePage(BuildContext context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => PageTwo()));
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Bloc pattern"),
),
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
StreamBuilder<String>(
stream: _bloc.email,
builder: (context, snapshot) => TextField(
onChanged: _bloc.emailChanged,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Enter Email",
labelText: "Email",
errorText: snapshot.error),
),
),
SizedBox(
height: 20,
),
StreamBuilder<String>(
stream: _bloc.password,
builder: (context, snapshot) => TextField(
onChanged: _bloc.passwordChanged,
keyboardType: TextInputType.text,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Enter password",
labelText: "Password",
errorText: snapshot.error),
),
),
SizedBox(
height: 20,
),
StreamBuilder<bool>(
stream: _bloc.submitCheck,
builder: (context, snapshot) => RaisedButton(
color: Colors.tealAccent,
onPressed: (snapshot.data != null)
? () => changethePage(context)
: null,
child: Text("Submit"),
))
],
),
),
),
);
}
}

关于google-app-engine - Rx.combineLatest2无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60575135/

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