Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 在省道/颤振中形成块状图案的最佳实践_Flutter_Dart_Bloc - Fatal编程技术网

Flutter 在省道/颤振中形成块状图案的最佳实践

Flutter 在省道/颤振中形成块状图案的最佳实践,flutter,dart,bloc,Flutter,Dart,Bloc,在flatter中使用BLoC模式时,在构造应用程序代码时,什么是良好的编程实践 这是一个松散的问题,所以我将尝试给出一个例子。假设您定义了一个BLoC类来处理特定小部件的验证,并且希望在填充表单时通过发出各种事件来更新验证消息 据我所知,您的集团可能看起来如下所示: import 'dart:async'; import 'package:myproject/bloc/base_bloc.dart'; import 'package:rxdart/rxdart.dart'; class Si

在flatter中使用BLoC模式时,在构造应用程序代码时,什么是良好的编程实践

这是一个松散的问题,所以我将尝试给出一个例子。假设您定义了一个BLoC类来处理特定小部件的验证,并且希望在填充表单时通过发出各种事件来更新验证消息

据我所知,您的集团可能看起来如下所示:

import 'dart:async';
import 'package:myproject/bloc/base_bloc.dart';
import 'package:rxdart/rxdart.dart';

class SignUpBloc extends Bloc {
    BehaviorSubject<String> _emailSubject;
    BehaviorSubject<String> _nameSubject;
    BehaviorSubject<String> _phoneSubject;
    BehaviorSubject<String> _signUpSubject;

    SignUpBloc() {
        _emailSubject = new BehaviorSubject<String>.seeded('');
        _nameSubject = new BehaviorSubject<String>.seeded('');
        _phoneSubject = new BehaviorSubject<String>.seeded('');
        _signUpSubject = new BehaviorSubject<String>.seeded('');
    }

    void nameChanged(String content) {
        if (content?.isEmpty ?? true) {
          _nameSubject.emit('Name is required for the sign-up process');
        } else {
           _nameSubject.emit('');
        }
    }

    void emailChanged(String content) {
        if (!_validEmail(content)) {
          _emailSubject.emit(
              'Please enter a valid email address (e.g. example@mydomain.com');
        } else {
          _emailSubject.emit('');
          _email = content;
        }
    }

    .
    .
    // Other functions are used to emit various messages here
    .
    .

    Stream<String> get emailStream => _emailSubject.stream;
    Stream<String> get nameStream => _nameSubject.stream;
    Stream<String> get phoneStream => _phoneSubject.stream;
    Stream<String> get signUpStream => _signUpSubject.stream;
}
导入'dart:async';
导入“包:myproject/bloc/base_bloc.dart”;
导入“包:rxdart/rxdart.dart”;
类SignUpBloc扩展了Bloc{
行为主体(emailSubject);;
行为主体(名称主体),;
行为主体(电话主体),;
行为主体——签名主体;
SignUpBloc(){
_emailSubject=新行为主体。种子(“”);
_nameSubject=新行为Subject.seeded(“”);
_phoneSubject=新行为主体。种子(“”);
_signUpSubject=新行为Subject.seeded(“”);
}
无效名称已更改(字符串内容){
if(content?.isEmpty±true){
_emit('注册过程需要名称');
}否则{
_nameSubject.emit(“”);
}
}
无效电子邮件已更改(字符串内容){
如果(!\u有效邮件(内容)){
_emailSubject.emit(
'请输入有效的电子邮件地址(例如。example@mydomain.com');
}否则{
_emailSubject.emit(“”);
_电子邮件=内容;
}
}
.
.
//其他函数用于在此处发出各种消息
.
.
Stream get emailStream=>\u emailSubject.Stream;
Stream get nameStream=>\u nameSubject.Stream;
Stream get phoneStream=>\u phoneSubject.Stream;
Stream get signUpStream=>\u signUpSubject.Stream;
}
…然后在ui/视图中,您可以执行以下操作:

StreamBuilder<String>(
      stream: _bloc.emailStream,
      builder: (context, snapshot) {
        return Padding(
          padding: EdgeInsets.only(top: 5.0),
          child: Text(
            snapshot?.data ?? '',
          ),
        );
      },
StreamBuilder(
stream:_bloc.emailStream,
生成器:(上下文,快照){
返回填充(
填充:仅限边缘设置(顶部:5.0),
子:文本(
快照?.data???“”,
),
);
},

现在,对我来说,这段代码散发出一种糟糕的代码味道……特别是,继续定义行为对象,然后编写方法来访问相应的流似乎有点混乱。我在网上找到的所有示例都定义了一种与此非常类似的方法,同时允许业务逻辑与在UI中,似乎有很多重复的工作来定义和公开主题。

虽然您的方法在某些情况下是合理的,但像这样使用
Bloc
感觉是多余的

Bloc
本身有两个流(内置、抽象),一个用于事件,一个用于状态

按照您的示例,使用Bloc的更惯用方法如下所示:

声明:

@不可变
抽象类FormState{
最终字符串电子邮件;
最后的字符串名;
最终字符串电话;
最终字符串注册;
最终字符串错误;
最终字符串名称错误;
最终字符串错误;
最终字符串签名错误;
FormState({
此电子邮件=”,
this.name=“”,
此.电话=”,
此。注册=“”,
this.emailError=“”,
this.nameError=“”,
this.phoneError=“”,
this.signuperor=“”,
});
}
活动:

@不可变
抽象类FormChangedEvent{
最终字符串电子邮件;
最后的字符串名;
最终字符串电话;
最终字符串注册;
FormChangedEvent({
此电子邮件=”,
this.name=“”,
此.电话=”,
此。注册=“”,
});
}
集团:

class FormBloc扩展了Bloc{
FormBloc():super(FormState());
@凌驾
流mapEventToState(FormChangedEvent事件)异步*{
屈服形态(
电子邮件:event.email,
名称:event.name,
电话:event.phone,
注册:event.signUp,
emailError:(event.email==null | | event.email.isEmpty)
?“此字段不应为空!”
: "",
nameError:(event.name==null | | event.name.isEmpty)
?“此字段不应为空!”
: "",
phoneError:(event.phone==null | | event.phone.isEmpty)
?“此字段不应为空!”
: "",
signUpError:(event.signUp==null | | event.signUp.isEmpty)
?“此字段不应为空!”
: "",
);
}
}
通过该设置,您可以使用来监听您的Bloc的状态更改。在本例中,您将收到
FormState
的实例,其中包含整个表单的状态

接下来,您可以创建事件和状态子类,并使用
is
状态正在加载,
状态为FormReady
)根据需要呈现页面的不同状态


我希望这能有所帮助。:]

这正是我想要的,谢谢。在您的回答后面,您是建议将RxDart库与BlocBuilder结合使用,还是BlocBuilder提供了足够的功能?另外(对于重复发布,我深表歉意),在您的示例中,事件数据实际上是如何传递到bloc的?您能在UI代码中显示它是什么样子吗?使用Rx很大程度上取决于您的用例。我肯定会在bloc中使用Rx来合并来自数据层(网络+数据库)的流例如,在使用Bloc时,我想不出UI端Rx的用例,但这可能是因为我缺乏想象力。在UI端,我会使用a在小部件树中设置一个Bloc,然后通过
BlocProvider.of(context)
访问它。您可以调用
add(event)
,查看结果(这当然是被要求的集团)。