理解Flux机制和应用

ReactJS是fackbook推出的UI组件框架,最主要特点就是引入了虚拟DOM的机制,并且提供一个非常优秀的UI组件框架,实现可复用的Web前端组件成为可能。

但是ReactJS基本上就是帮助你来开发一个可复用的Web组件的框架,缺少数据双向绑定,依赖注入、绑定等一大堆特性。

而在前端开发时,往往需要提供一个完整的机制来进行DOM、数据的管理,由此,各类前端MVVM框架大为流行,像AngularJS就是一个非常流行的MVVM框架。


Flux就是facebook提供的一个类似MVVM的设计模式或架构,但是facebook只提供了Flux的设计思路和原理,ReactJS本身并没有实现Flux的完整的库,我们可以按照其设计

思想自行实现。

Flux的设计思想见下图:



Flux架构中包括Action(行为)、Dispatcher(调度器)、Store(存储)、View(视图),相对常见的MVVM框架,Flux设计思想中最大的特点是数据是单向流动的,像AngularJS可以双向绑定,这在Flux中是不允许的。双向绑定在Model和DOM中直接进行绑定,看起来很爽,当页面复杂时就会较多的问题。

关于Flux的具体原理本文不想仔细介绍,见这里


以下结合ReactJS来详细介绍一下如何实现一个Flex应用。


1、概念


Action(行为):或动作,如增加操作、删除操作、更新操作,就是一堆函数。

Dispatcher(调度器):负责进行事件的分发调度。facebook提供了一个现成的Dispatcher(叫Flux.js,Github里面有)可以直接用。注意的是Flux,js是为nodejs开发的模块,如果要有浏览器中使用需要稍微改造一下。

Store(存储):就是用来保存数据的地方,或者相当于Model层。

View(视图):在ReactJS中就是各类component.


2、创建Dispatcher(调度器)


 建一个全局的调度器.


  先引入<script src="js/dispatcher.js"></script>
   dispatcher.js是从Flux,js中改造成可以在浏览器中使用。

 var AppDispatcher = new Dispatcher();


3、定义action行为

定义一个全局变量来保存各种action,action就是一个普通的JS函数,如下:

      var CommentActions = {
        create: function(author,text) {
          //向调度中心注册发布事
          AppDispatcher.dispatch({
            actionType:"create",        //动作类型
            author:author,
            text: text
          });
        }
      };

最主要的是里面的
AppDispatcher.dispatch

这个方法需要你提供一个必备的actionType参数,用来说明这个action。其他参数则是这个action需要的。

可以理解为该方法将action注册到调度器中,调度可以根据actionType来执行不同的store操作。

你也可以增加像delete,update等各种action。类似这样:

var CommentActions = {
        create: function(author,text) {
          //向调度中心注册发布事
          AppDispatcher.dispatch({
            actionType:"create",        //动作类型
            author:author,
            text: text
          });
        },
        delete:function(index){
     <span style="font-family: Arial, Helvetica, sans-serif;">          AppDispatcher.dispatch({</span><pre name="code" class="javascript">            actionType:"delete",        //动作类型
            author:author,
            text: text
          });
} };
 

4、创建store

store就是一个用来保存数据的仓库,你可以按自己的需要进行管理数据,也可以从ajax提取数据等,像下例,就是采用一个数组来保存数据。

     //存储数据
      var CommentStore = {
        items: [],
        getAll: function() {
          return this.items;
        },
        getItem:function(index){
          return this.items[index];
        },
        onChange:function(author,text){
          console.log("onChange");
          this.items.push({"author":author,"text":text});
        }
      };

上例中的CommentStore就是一个全局变量。

接着调用AppDispatcher.register,通过传Dispacher传入的action参数来决定该如何进行CommentStore操作。

AppDispatcher.register(function(action) {

        var text;
        switch(action.actionType) {
          case "create":            <pre name="code" class="javascript">           CommentStore<span style="font-family: Arial, Helvetica, sans-serif;">.items.push({"author":author,"text":text});</span>
//触发change事件 CommentStore.trigger('change',action.author,action.text); break; } });
 上面这个例子,当一个create action发生时,就添加一个数据项,然后触发一个change事件。 

重点来了,当action行为发生时,调度器通知store进行数据变更,这个过程是由调度器来完成。

而数据变更后,如何通知view更新呢?

机制就是通过事件和各种callback,在Flux.js的官方的todo例子中,用的是node的events模块来实现事件的注册、绑定和触发。

你也可以自己管理一个callback来处理事件。


在本文中,我使用的是一个叫MicroEvent.js的小型事件分发器,使用方法如下:

MicroEvent.mixin(CommentStore) 

这个方法执行后就为CommentStore提供bind、trigger、unbind等方法,并提供一个事件分发。

将这句MicroEvent.mixin(CommentStore) 加在:

var CommentStore = {
    MicroEvent.mixin(CommentStore)
}

然后就可以通过<pre name="code" class="javascript">CommentStore.bind("change",callback)绑定一个change事件。
CommentStore.trigger("change",params)触发一个change事件。
 

5、通知view改变


在上一小节中,store需要触发相应的事件,事件类型可以自己定义。那么view层如何进行更新呢?

在ReactJS中componentDidMount事件是指在组件渲染挂在DIM后发生的事件,很明显,由于ReactJS具有虚拟DOM的特点,因此

更新事件绑定,可以在componentDidMount事件中绑定上面的change事件,像这样:

var Comment = React.createClass({

<span style="white-space:pre">	</span>onChange:function(){
          在这里可以进行进行setState操作
        },
        componentDidMount:function(){
          <span style="font-family: Arial, Helvetica, sans-serif;">CommentStore.bind("change",this.onChange)   #通过这里的侦听事件</span>
        },
         componentWillUnmount:function(){        <pre name="code" class="javascript"><span style="font-family: Arial, Helvetica, sans-serif;">                          CommentStore.unbind("change")</span>
}})

 


6、小结

很明显Flux仅仅是个设计模式,跟ReactJS结合可以为大型应用提供最佳实践。





  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值