我已经编写了一些简单的flutter应用程序,这些应用程序使用状态小部件/表单/文本字段输入和管理数据。现在,我试图了解如何使用BLoC和streambuilder进行类似的工作。但是我不知道如何为我的字段设置初始值。
我试图创建一个最简单的示例,我可以使用bloc来制作一个微型应用程序。这只是将一个名称输入到TextField中,并将其回显到下一行。
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Bloc Example',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage();
String initialData = 'Fred';
@override
Widget build(BuildContext context) {
TextEditingController _controller = new TextEditingController();
return Scaffold(
appBar: AppBar(title: Text('Bloc Example')),
body: Center(
child: Column(
children: <Widget>[
StreamBuilder(
initialData: initialData,
stream: bloc.nameStream,
builder: (context, snapshot) {
if ( snapshot.connectionState == ConnectionState.waiting)
_controller.text = snapshot.data;
return TextField(
controller: _controller,
onChanged: bloc.nameChangedStream,
decoration: InputDecoration(labelText: 'Enter name' ),
);
}
),
StreamBuilder(
initialData: initialData,
stream: bloc.nameStream, //
builder: (context, snapshot) {
return Text('Name is ${snapshot.hasData ? snapshot.data : 'unknown'}');
}
),
],
),
),
);
}
}
class Bloc
{
final nameStreamController = BehaviorSubject<String>();
Stream<String> get nameStream => nameStreamController.stream;
Function(String) get nameChangedStream => nameStreamController.sink.add ;
}
final Bloc bloc = new Bloc();
我不知道如何为我的姓名字段指定初始值。
我必须承认,由于具有旧式编程背景,我花了一段时间才能将自己的思想投入到响应式编程中-但是向前还是向上!
编辑-感谢给出的注释-更新了代码以使用TextEditingController和StreamBuilder initialData的组合,并且似乎可以正常工作。如果有更好的解决方案,很高兴提出进一步的评论:)
答案 0 :(得分:2)
在不知道要使用“名称”字段做什么的情况下,您可以走几条路线。
您可以向hintText
(InputDecoration
)提供InputDecoration(hintText: 'name')
。
您可以在StreamBuilder上设置一个初始值:
StreamBuilder(
stream: bloc.nameStream,
initialData: 'Initial Name',
builder: (context, snapshot) {
return TextField(
onChanged: bloc.nameChangedStream,
decoration: InputDecoration(labelText: 'Enter name' ),
);
}
),
但是,这不会在流中保留该值,因此,如果用户不更改文本字段,则nameStreamController
的流中不会出现“初始名称”。
如@nonybrighto所述,您可以将nameStreamController
用作初始值。
如果您不能使用种子值,也可以在团体初始化期间向流中添加初始值:
class Bloc {
final nameStreamController = BehaviorSubject<String>();
Stream<String> get nameStream => nameStreamController.stream;
Function(String) get nameChangedStream => nameStreamController.sink.add;
Bloc() {
String initialValue = _getInitialValue();
nameStreamController.add(initialValue);
}
}
这是一个更完整的真实示例:我们找到了此身份验证和登录BLoC示例,在其中我们遵循了此处列出的许多内容:Didier Boelens BloC Example。它向您展示了如何使用BLoC,反应式编程和流来设置注册表单和身份验证。
答案 1 :(得分:0)
您可以为behaviorSubject提供一个种子值,该值将用作其初始值。
final nameStreamController = BehaviorSubject<String>.seeded('InitialName');
对于旧版本的rxDart,请使用
final nameStreamController = BehaviorSubject<String>(seedValue:'InitialName');