【问题标题】:How to give a default value to a textfield when using bloc framework使用 bloc 框架时如何为文本字段提供默认值
【发布时间】:2019-09-08 20:49:25
【问题描述】:

我编写了一些简单的 Flutter 应用程序,它们使用有状态的小部件/表单/文本表单字段来输入和管理数据。现在我正在尝试了解如何使用 BLoC 和流构建器来完成类似的工作。但我不知道如何为我的字段设置初始值。

我试图创建一个我能想到的最简单的例子,它是一个使用 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();

我不知道如何为我的姓名字段指定初始值。

我必须承认,我来自旧式编程背景,我需要一段时间才能让我的思想进入反应式编程 - 但越来越多!

编辑 - 感谢给定的 cmets - 更新了代码以使用 TextEditingController 和 StreamBuilder initialData 的组合,并且似乎工作正常。如果有更好的解决方案,很高兴采取进一步的 cmets :)

【问题讨论】:

  • 你能提供你使用的解决方案吗?

标签: dart flutter bloc


【解决方案1】:

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

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

对于旧版本的 rxDart,请使用

final nameStreamController = BehaviorSubject<String>(seedValue:'InitialName'); 

【讨论】:

  • 感谢您的建议。如果我在示例代码中添加种子值,我可以在 Text 小部件中看到 InitialName。但我仍在尝试让 TextField 将 InitialName 作为其初始值。我想我可以使用 TextFormField 并设置 initialValue,或者使用 TextEditingController - 但这些看起来都不是特别优雅。
【解决方案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

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

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、反应式编程和流来设置注册表单和身份验证。

【讨论】:

  • 我们完全忘记了在 nonybrighto 提出时为您的流控制器播种。我会走那条路,而不是在初始化期间添加值,如上一个示例所示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 1970-01-01
  • 2012-01-23
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多