上回说到,Reflux将React之间多个组件之间的通讯问题解决了,保证了这个应用的数据统一,总结一下就是:react
Component是一个界面渲染角色,会有本身的状态,能够传递属性程序员
Actions是用户操做的接口,它并无Controller那样强大的控制能力,个人理解是定义了一个操做的内部RESTFUL操做规范,每个涉及到数据的操做,都必须经过actions,这样对于之后复杂的流程和数据模型,咱们内部不用把界面写得乱七八糟。swift
Store是存储数据的地方,也就是MVC中的Modal,可是不少逻辑咱们又不得不放在Store里面,因此Store更像Controller。Store的数据一旦变化,它会通知各个监听他的组件对象,从新对界面进行渲染。后端
这一章,咱们仍是拿UserActions和UserStore来举例说明,在咱们的项目中,如何更好的使用Reflux。this
目前咱们的UserActions是这样的:lua
var UserActions = Reflux.createActions({code
'register' : {children:["success","failed"]}, 'login' : {children:["success","failed"]}, 'loginWithToken' : {children : ['success','failed']}, 'logout' : {children:["success"]}, 'openLogin' : {children:["success","failed"]}, 'currentUser' : {children:["success","failed"]}, 'modifyPassword':{children:["success","failed"]}
});
看action的命名应该就知道大概的用途了,这里不细说。咱们的UserStore是这样初始化的:component
init: function() {对象
console.log('UserStore initialized'); /* 须要增长从localStorage读取用户信息的方法来初始化userData */ this.userData = { userId: '', userName: '', loginToken : '',//用户选择rememberme的时候返回 userType: '', userState: '', isLogin: false, hintMessage: '', flag : '' }; /* 获取第三方登陆的返回值,并获得当前用户 */ UserActions.currentUser(); /* 能够用下面代码代替 listenables: UserActions, */ this.listenTo(UserActions.login.success, this.onLoginSuccess); this.listenTo(UserActions.login.failed, this.onLoginFailed); this.listenTo(UserActions.register.success, this.onRegisterSuccess); this.listenTo(UserActions.register.failed, this.onRegisterFailed); ....
},
咱们定义了一个userData对象,会存储当前的用户信息,若是没有登陆状态,isLogin是false。请注意,咱们在UserStore里面会初始化调用一个UserActions.currentUser().也就是说在页面一加载的时候,咱们就会调用获取当前用户的登陆信息。token
获得用户信息的反馈以后:
onGetCurrentUser : function(data){
if(data.Success){ console.log(data); this.setCurrentUser(data); this.userData.flag = 'currentUser'; this.trigger(this.userData); }else{ console.log(data.ErrorMsg); //若未获得当前用户,尝试loginwithtoken this.getTokenToLogin(); }
},
很容易明白上面的代码,若是后端返回成功,设置当前用户,若是后端失败,尝试用本地的loginToken登陆。可是注意到了没有,为何会有一个flag呢?固然你可能根本没有注意到。。。。
flag是我本身定义的一个标记,并非Reflux的定义,为何要定义?回头看看UserActions的代码,发现那么多的actions都是调用同一个UserStore,用户登陆、注册、三方登陆、修改密码等等。监听UserStore的组件至关多,通常涉及到须要当前用户登陆才能操做的界面基本上都要监听UserStore,若是无论进行什么操做,这些组件都要听到UserStore数据变化的消息,那不就烦(luan)死(tao)啦。因此,咱们针对每个不一样的actions操做返回的结果定义一个flag,在不一样的组件监听方法里面判断此次数据的变化是否是我想要听到的,若是不是就无论他。
因而component里面的代码就是这样的:
//login.js
handleLoginResult : function(data){
if(data.flag == 'login' || data.flag == 'currentUser' || data.flag == 'loginToken'){ if(data.hintMessage){ this.handleHint(data.hintMessage); }else{ //登陆成功,跳转到account界面 console.log('登陆成功'); this.history.pushState(null,'/account'); } }
},
固然,对于UserStore里面的信息是很是重要的,因此对于它而言,通常须要登陆才能操做的界面,咱们直接不判断他是从哪登陆的,只要登陆就行,就不用判断flag。好比摄影师的编辑页面是这样的监听方法:
handleUserStoreChange : function(userData){
if(userData.isLogin){ if(userData.userType == 1){ //已是摄影师用户,跳转摄影师信息 this.history.pushState(null,'/account/photographer'); }else{ //普通用户,拿到认证数据再判断认证状态 this.getAuditData(); } }else{ //没有登陆转到登陆界面 this.history.pushSate(null,'/'); }
},
对于程序员而言,代码是最能说明事情的方法,因此大量的引用了代码,对于大家的困扰,我说声抱歉。固然,若是你能仔细看懂上面的例子,目前对于咱们的项目而言,处理各类类型的逻辑应该是不成话下了。
未完待续,下一篇讲讲Router,其实我更想讲讲react-native,算了,这两天搞的头大,直接上swift了。