- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是使用 flutter 的新手。我试图在flutter中创建一些示例应用程序以创建自己的应用程序。我发现了带有团块模式的 flutter 打中很好的应用程序。请参阅以下 link 。
这只是一个登录页面。表单中有一个带有验证的电子邮件和密码文本框。一个验证器用于电子邮件,另一个验证器用于密码长度。表单中有一个提交按钮,最初已禁用,如果电子邮件和密码成功验证,则启用提交按钮。它使用带有 rxdart 软件包的块模式架构。
我在提交按钮验证方面遇到问题,在输入电子邮件和密码字段后,未启用按钮字段。
按钮验证码
Stream<bool> get submitCheck =>
Rx.combineLatest2(email, password, (e, p) => true);
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"),
))
],
),
),
),
);
}
}
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();
}
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方法中创建块,并在StatefulWidget
的dispose方法中处理该块。
而且您的StreamController的Stream
仅支持一个订阅者,因此,如果您希望Stream
的StreamController
可以被监听多次,则需要将其作为广播流,其中一种方法是使用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/
使用运行 rxjs 迁移工具后 rxjs-5-to-6-migrate -p src/tsconfig.app.json 我现在收到一个 linting 错误: combineLatest is de
我遇到了 rxjs 和 combineLatest 方法的问题。我试图在 combineLatest 中调用 combineLatest 并且它不起作用,尽管它返回 Observable 对象。请帮助
如何通过combineLatest组合Observables。 mergeLatest 未定义 我正在使用 Angular js 7。我想 Marge 拖曳查询字符串参数,但是当我编写 obserab
我有 3 个事件需要合并,当其中一个被触发时,调用服务。我使用了 combineLatest,但只有当第一个事件被 filterChanged 触发时它才有效。 filterChanged 是一个本地
我很难理解为什么 combineLatest没有返回最新值。这个例子有点做作,但至少它说明了我的问题。注意 color 的值来自 combineLatest observable 返回先前的值,当 s
我有一个带有频繁值的流和一个带有较慢值的流。我想将它们组合起来,但只在较慢的一个发出时才发出一个值。所以combineLatest不起作用。 像这样: a1 a2 b1 (a2,b1) a3 a4 a
我有一些观察结果。我需要知道哪个触发了订阅。 Observable.combineLatest( this.tournamentsService.getUpcoming(),
我对以下重载感兴趣: public static IObservable> CombineLatest(this params IObservable[] sources); public stati
我想知道我的应用程序何时离线并恢复在线。我在 rxjs 中注册了以下事件: const online = Rx.Observable.fromEvent(window, 'online'); cons
如果我有两个 SignalProducers(实际上它们是 API 服务请求,所以它们只发送一次“下一个”),并将它们与 combineLatest 组合(因为我想在两者完成后关闭加载微调器),如果其
我有一个从后端获取数据的 Angular 解析器。我有以下调用要执行: GetProject(projectId): Observable GetSites(projectId): Observabl
我正在用 FLUTTER/DART 和 RXDART 做一个小项目。 部分代码如下: class RegisterBloc with UserValidator { final _username =
我正在尝试关注 this example 但在使用 combineLatest() 时遇到问题: Property 'subscribe' does not exist on type 'Operat
我需要将来自两个来源的数据合并为一个 res: {data1: any, data2: any}对象,我需要实现这个 即使其中一个源不发出任何值 这是我期望的结构: xxx ( source1
我有一个主页页面,用户在其中点击联系我即可重定向到联系页面: home.component.html Contact me home.component.ts: import { Compon
我想执行一些顺序代码,但我无法从 combineLatest 中提取数据 const { datosPersona, participante } = await combineLatest( t
我有两个 observable 想与 combineLatest 结合起来: const o1 = from(['a', 'b', 'c']); const o2 = of('content from
我需要在这个 combineLatest 中处理每个函数的错误场景。我会在下面添加代码 const combined = combineLatest( this.myservice1.fn1(pa
我有 3 个可观察的事件流 - 按日期顺序 -(主要事件、有关销售的事件和有关客户的事件) - 每个流都包含一种与各种车辆相关的事件,每个事件都有一个 vehicleID 和各种其他事件特性。事件可以
我需要一种方法将值从一个 observable 传递给两个函数,每个函数都接受一个值,每个函数依次返回一个 observable(只发出一个值,然后完成)。我希望 .combineLatest() 允
我是一名优秀的程序员,十分优秀!