上一篇文章,我们介绍了如何在flutter中使用redux。在上一篇文章的例子中,我们使用了单界面集成redux,但是在实际项目中,我们通常涉及多个模块,每个模块涉及多个界面,那么如何使用redux整合模块,并实现模块和界面间的消息传递呢?

例子:登录

接着上篇文章,这次的例子稍微复杂一点:

目标:

  • 实现登录界面,实现基本登录逻辑
  • 成功之后将结果通知到其他界面

先将AppState等状态有关的移动到reducers.dart,创建LoginPage.dart

LoginPage.dart代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:flutter_use_redux/reducers.dart';
import 'package:redux/redux.dart';
import 'dart:async';
import 'package:flutter/cupertino.dart'; typedef Future CallLogin(String account,String pwd); class LoginPageState extends State<LoginPage>{ String _account;
String _pwd; bool isLogin; @override
void initState() {
super.initState();
} @override
void dispose() {
super.dispose();
} @override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("登录"),
),
body: new Form(
onChanged: (){
print("changed");
},
onWillPop: () async{
return true;
},
child: new Padding(padding: new EdgeInsets.all(10.0),child: new Column( children: <Widget>[
new TextFormField( decoration:new InputDecoration(labelText: "请输入账号") ,
onSaved: (String value){
_account = value;
}, ///保持一下输入的账号
validator: (String value)=> value.isEmpty ? "请输入账号" : null, ),
new TextFormField(decoration:new InputDecoration(labelText: "请输入密码"),
onSaved: (String value)=>_pwd = value, ///保持一下输入的密码
validator: (String value)=> value.isEmpty ? "请输入密码" : null),
new FormField(builder: (FormFieldState s){
return new Center(
child: new RaisedButton(onPressed: () async{ FormState state = Form.of(s.context);
if(state.validate()){
//如果验证成功,那么执行登录逻辑
state.save();
print("Login success $_account" );
//这里交给设置好的逻辑去执行操作
try{
await widget.callLogin(_account,_pwd);
showDialog(context: context,builder: (c){ return new CupertinoAlertDialog(
title: new Text("登录成功"),
actions: <Widget>[
new Center(
child: new RaisedButton(
onPressed:(){
Navigator.of(context).pop();
Navigator.of(context).pop();
},
child: new Text("ok"),
)
)
],
); });
// Navigator.of(context).pop();
}catch(e){
showDialog(context: context,builder: (c){ return new CupertinoAlertDialog(
title: new Text("登录失败$e"),
actions: <Widget>[
new Center(
child: new RaisedButton(
onPressed:(){
Navigator.of(context).pop();
},
child: new Text("ok"),
)
)
],
); });
///登录失败,提示一下用户
print("登录失败! $e");
} } },child: new Text("提交"),)
);
})
], ),)),
);
} } class LoginPage extends StatefulWidget{ CallLogin callLogin; LoginPage({this.callLogin}); @override
State<StatefulWidget> createState() {
return new LoginPageState();
} }

注意:这个组件其实并没有使用redux,登录逻辑使用外部传递过来的函数来处理:

 CallLogin callLogin;
LoginPage({this.callLogin}); ...
//执行登录逻辑
await widget.callLogin(_account,_pwd);
...

为什么要这么做呢?好处有哪些?

  • 减少组件之间的依赖关系
  • 减少本类的职责,将本类的职责变成只展示ui
  • 本类可单独单元测试,单独工作,只要传进来一个模拟的逻辑函数

那么在哪里将登录逻辑传递进来呢?

···
routes: {

    "login":(BuildContext context)=>new StoreConnector(builder: ( BuildContext context,Store<AppState> store ){

      return new LoginPage(callLogin: (String account,String pwd) async{
print("正在登录,账号$account,密码:$pwd");
// 为了模拟实际登录,这里等待一秒
await new Async.Future.delayed(new Duration(milliseconds: 1000));
if(pwd != "123456"){
throw ("登录失败,密码必须是123456");
}
print("登录成功!");
store.dispatch(new LoginSuccessAction(account: account)); },);
}, converter: (Store<AppState> store){
return store;
}),

···

在导入这个登录组件到应用程序路由上面的时候,这个时候将逻辑和Store进行对接,这样做,就将逻辑和ui彻底的分开了。

这里涉及到异步操作,那么就会遇到所谓“副作用”问题。
随着项目的增大,reducer也会越来越大,那么有什么办法可以管理呢?
这些问题我们改天再分享。

附件:

老规矩,代码在这里:
https://github.com/jzoom/flut...

如有疑问,请加qq群854192563讨论

最新文章

  1. SQL语句/函数汇总
  2. linux 防火墙配置
  3. 【原创】C#通用权限管理-程序安全检查,这些你一定要考虑到位
  4. 【学习/研发】嵌入式Linux/Android开发有它就够了——迅为4412开发板
  5. 【HDOJ】2510 符号三角形
  6. 我的天哪,现在的移动VIN码识别已经这么。。
  7. WebService 的工作原理
  8. NOI真题记录
  9. sqlmap的安装
  10. MySQL中exists和in的区别及使用场景
  11. Android百度地图2.0运行定位到当前位置时“服务没有启动”
  12. Spring(二十二):Spring 事务
  13. ARM 汇编的mov操作立即数的疑问
  14. Memcached 运行状态
  15. 201621123008《Java程序设计》第七周学习总结
  16. 不开vip会员照样看vip电影(亲测有效)
  17. CodeForces 593D Happy Tree Party [LCA+并查集]
  18. java JAXB + STAX(是一种针对XML的流式拉分析API)读取xml
  19. shell脚本自带变量的含义
  20. CMake是用于生成make文件的跨平台编译文件

热门文章

  1. C++不被继承的内容
  2. python图片拼接
  3. Linux学习,账号管理与权限管理
  4. 2018蓝桥杯省赛(C/C++ C组)
  5. 中阶d03.1 JDBCDemo
  6. MODIS系列之NDVI(MOD13Q1)四:MRT单次及批次处理数据
  7. 五分钟!用python绘制漂亮的系统架构图
  8. 熬夜整理出来的干货:Python+Pycharm+PyQT5可视化程序设计入门
  9. G. 蚂蚁的镜像串
  10. UML(续)