使用bloc框架时如何为文本字段提供默认值

问题描述 投票:0回答:2

我写了一些简单的颤动应用程序,它们使用有状态的小部件/表单/ textformfields来输入和管理数据。现在我试图了解如何使用BLoCs和streambuilders来做类似的工作。但我无法弄清楚如何为我的字段设置初始值。

我试图创建一个最简单的例子,我可以想出一个使用集团的小应用程序。这只是一个输入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的组合,似乎工作正常。如果有更好的解决方案,很高兴进一步评论:)

dart flutter bloc
2个回答
2
投票

如果不知道你想用名字字段做什么,你可以去几条路线。

你可以向hintTextInputDecoration)提供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

如果您不能使用种子值,您还可以在bloc的init期间向流添加初始值:

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
投票

您可以通过执行此操作为behaviorSubject提供将用作其初始值的种子值。

final nameStreamController = BehaviorSubject<String>.seeded('InitialName');  

对于旧版本的rxDart,请使用

final nameStreamController = BehaviorSubject<String>(seedValue:'InitialName'); 
© www.soinside.com 2019 - 2024. All rights reserved.