标签:
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();
定义一个全局变量来保存各种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事件。
在上一小节中,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结合可以为大型应用提供最佳实践。
标签:
原文地址:http://blog.csdn.net/wenxuansoft/article/details/46640299