flutter全局数据共享通知方案

让咱们先抛开Flutter这个平台说话,若是让你实现数据共享,你能想到的基础方案有哪些。
  • 全局静态变量
  • 单例(XXXMnager,如UserManger)
  • 持久化(SharePref)
ok,以上方案真的是简单粗暴,好用到哭,然而,设计到数据数据变动以后及时通知到各个关注方就显得有点捉襟见肘了。
所以,由于有这样的一些需求存在,业界的一些大神(懒人)们经过不懈的努力,作出了一些惊天地,泣鬼神的全局数据共享通知方案。
那么,在flutter上,我比较关注的是, Redux,和 event_bus 了,本文就是想来总结一下本身对Redux和event_bus的理解心得。

Redux

理解成本比较高,我的以为耦合性也比较高,要搞清楚redux的原理,先要了解一下几个概念

Store

这里是他的构造函数,咱们先不要管里面的一堆参数,看一眼就好。
Store(
    this.reducer, {
    State initialState,
    List<Middleware<State>> middleware = const [],
    bool syncStream: false,

    /// If set to true, the Store will not emit onChange events if the new State
    /// that is returned from your [reducer] in response to an Action is equal
    /// to the previous state.
    ///
    /// Under the hood, it will use the `==` method from your State class to
    /// determine whether or not the two States are equal.
    bool distinct: false,
  })复制代码
Store能够简单的理解为一个容纳各类数据以及对数据处理的action的一个仓库,能够看到能够给它配置一个泛型,这个泛型表明的就是下面的State,好,咱们接着看State。

State

State实际上并非Dart的基础类型,他其实就是上面Store定义中的那个S,对的,他就是一个泛型,他能够是dart基础类型String,int,double,也能够是你定义的class,都ok。总之一句话,他就是Store要守护的和维护的那个份数据。

StoreProvider

这里是他的构造函数,这里的参数比较简单,能够直接就了解一下
const StoreProvider({
    Key key,
    @required Store<S> store,
    @required Widget child,
  })复制代码
一个store,一个child是一个Widget类型,因此理解起来是否是就是将这个store和child绑定起来的桥梁啊,嗯,牵线媒婆,store中的数据有变动能够通知到到child更新tree,那么具体child中的哪些个子child须要更新,是有谁决定的,固然是StoreConnector,媒婆把人给你放一块儿,你牵不牵手他可无论,谁管,确定是StoreConnector啊,好,咱们看StoreConnector。

StoreConnector

仍是来看一下构造函数
StoreConnector({
    Key key,
    @required this.builder,
    @required this.converter,
    this.distinct = false,
    this.onInit,
    this.onDispose,
    this.rebuildOnChange = true,
    this.ignoreChange,
    this.onWillChange,
    this.onDidChange,
    this.onInitialBuild,
  })复制代码
这个构造函数的参数就有点多了,若是你感兴趣能够都了解一下,没时间的话,只须要了解required标记的。第一个是builder,这个就是WidgetBuilder,很明显,构建view用的,很是重点的converter这个参数,看一下converter的定义:
/// Convert the entire Store into a ViewModel. The ViewModel will be used

/// to build a Widget using the ViewModelBuilder.

typedef StoreConverter<S, ViewModel> = ViewModel Function(

  Store<S> store,

);复制代码
看到以后也就没那么神秘了,就是将store转换为了ViewModel,转了以后,实际上就是能够更好的将数据交给builder去构建view,是吗?难道不是吗?咱们前面提到了store能够接受到一个改变里面数据的action,那么这些action是谁给处理的呢?回过头来看Store的构造函数,里面的第一个参数是reducer,reducer的英文翻译为减速器,还原剂,反正就是听着挺别扭的,他不就是一个状态转换器嘛,数据有一个状态,通过action的处理,变成另一个状态,是吗,这样你好理解了么?好吧,来看看Reducer。

Reducer

Reducer的定义以下:
typedef State Reducer<State>(State state, dynamic action);复制代码
一目了然,就是上面所说的状态应该action处理,变为另一个状态,那么,state的处理仅仅只有Reducer处理,加入须要加入一些日志记录的,性能监控等处理,该怎么办呢?这种需求处处都有啊,大名鼎鼎的okhttp,处理一个http请求也能够说成是一个一系列的请求参数json请过action后端服务器的处理变为另一串json,对么,那么对请求头,请求参数校验的一些处理,是否是都交给了拦截器interceptor?这点设计思路是想通的,所以这里的Middleware中间件虽然叫起来很神秘,可是他实际上就是拦截器,他在Reducer们以前执行,这点我了解到的是如此,有不一样的看法的同窗能够在评论中留下建议。

Middleware

定义以下
/// ### Example
///
///     loggingMiddleware(Store<int> store, action, NextDispatcher next) {
///       print('${new DateTime.now()}: $action');
///
///       next(action);
///     }
///
///     // Create your store with the loggingMiddleware
///     final store = new Store<int>(
///       counterReducer,
///       middleware: [loggingMiddleware],
///     );
typedef void Middleware<State>(
  Store<State> store,
  dynamic action,
  NextDispatcher next,
);复制代码
对,处理完以后,交给后面的action,理解起来也没什么成本了,好,那么总结一下咱们将的这些概念,将他们串起来,用一副图来表达。


用一句话来描述就是:
store经过storeProvider将本身给暴露出来,交给StoreConnector来更好连接到控件上,控件(也不必定须要在控件哪里,只不过咱们好理解点)发送action交给store中的reducer处理,若是有中间件存在,那么中间件先拦截以后在交给recuder处理。处理以后store中的数据变动了,将会经有storeConnector通知组件更新。ok流程就这么跑完了。

event_bus

理解成本略低,耦合性也较低
初始化
import 'package:event_bus/event_bus.dart';

EventBus eventBus = new EventBus();复制代码
发送事件
eventBus.fire(event);复制代码
监听事件
eventBus.on().listen((event) { 
    print(event.runtimeType);
});复制代码
也没有太多的概念,无耻的盗一幅图来讲就是


用一句话总结就是:对于某处所作的变动,若是想通知出去,那么交给总线吧,谁想关心谁问总线取。

总结

整体上来看,redux和bus均可以实现全局数据共享及变动通知,可是bus更加好理解概念也每有那么多,也不像redux须要经过storeConnector那么与控件绑定,形成没必要要的耦合,我的倾向于使用bus解决全局数据共享变动通知的需求。


Flutter Event Bus 实现原理传送门

相关文章
相关标签/搜索