Reflux中文教程——action
翻译自github上的reflux项目,链接:https://github.com/reflux/refluxjs/tree/master/docs/actions
一、概览
在Reflux中,actions是store可以监听的函数。action发送一个事件,监听它的store的单例实例就会收到,但调用形式跟函数一样。
二、创建actions
在Reflux中,创建action有多种方式。两种主要方式是Reflux.createAction(创建一个) 和Reflux.createActions(一次性创建多个)。
Reflux.createAction接收一个可选的定义对象作为参数,返回action本身。
Reflux.createActions接受定义对象的数组,返回一个数组,数组中每个元素都可以创建一个action。
Reflux.createActions还有一个简写法,用对象代替数组,它为对象的每一个属性都创建一个action,名字就是属性。
分别举例如下:
var singleAction = Reflux.createAction();
var ManyActions = Reflux.createActions(['action1', 'action2']);
var MoreActions = Reflux.createActions({'anAction':{}});
singleAction();
ManyActions.action1();
MoreActions.anAction();
action创建函数可以接受一个参数,可能是下面这种格式
let myActions = Reflux.createAction({
actionName: "myActionName",//name
children: ['childAction'],//子actions的name(),用于异步操作
asyncResult: true,//
sync: false,//设置action是同步还是异步,默认同步,除非有children
preEmit: function(){},
shouldEmit: function(){}
});
这些属性都不是必须的,甚至你可以不带任何参数创建actions,甚至还有设置actionName更简便的方法。
// examples of #1 above
var action = Reflux.createAction('myName');
var Actions = Reflux.createActions(['myName1', 'myName2']);
// both are equivalent to (respectively):
var action = Reflux.createAction({actionName:'myName'});
var Actions = Reflux.createActions([{actionName:'myName1'}, {actionName:'myName2'}]);
// examples of #2 above
var Actions = Reflux.createActions({'myName1':{sync:false}});
// is equivalent to:
var Actions = Reflux.createActions([{actionName:'myName1', sync:false}]);
异步 VS 同步 actions
actions可以通过myAction()被调用,很简单。但是在内部,如果action的sycn设置为true,action就会执行action.trigger(),不过不是,就执行action.triggerAsycn()。两者的区别在于前者是立即触发,后者在下一个事件循环中触发,可能有能被调用的child action。
action默认都是同步,除非在定义对象中特别指定,或者里面有child action
通过子actions 进行异步加载
通过子actions你可以完成真正的异步actions如文件加载。一个action可以执行一个异步任务,当任务完成时调用子action。最简单的形式如下:
var action = Reflux.createAction({children: ['delayComplete']});
action.listen(function () {
setTimeout(this.delayComplete, 1000);
});
当监听这个actions时可以用this.listenTo(action.delayComplete, onActionDelayComplete). 当调用delayComplete传递的参数会传递给listener的回调函数。这样,比如你在加载文件这样的事情时,就有了函数可以传递文件内容给监听者。
最常见的应用方式就是用createActions 和 简写法(Reflux store 的this.listenable 和this.listenToMany)。store可以自动的给action设置监听函数,以action的名字actionName或者驼峰写法onActionName,子actions也一起也有了监听函数,actionNameChildAction或者onActionNameChildAction。这里是个例子:
var Actions = Reflux.createActions({
'load': {children: ['completed', 'failed']}
});
Actions.load.listen( function() {
someAsyncOperation()
.then( this.completed )
.catch( this.failed );
});
class MyStore extends Reflux.Store {
constructor(props){
super(props);
this.listenables = Actions;
// or
this.listenToMany(Actions);
}
onLoadCompleted(data) {
// use the data here
}
onLoadFailed(message) {
// failed, with whatever message you sent
}
}
三、监听
主要监听方式就是在store中用this.listenTo(action, callbackFunc)或者this.listenables = actions 。但是别忘了,也可以直接监听action或者子action的。
MyActions.actionName.listen(myCallbackFunc);//直接监听
MyActions.load.completed.listen(myCallbackFunc);//监听子action
四、移除监听
创建监听时,会返回一个取消监听的函数,调用这个函数就可以了。
var unsubscribe = myActions.actionName.listen(myCallbackFunc);
unsubscribe();
五、Action Hooks
有几个钩子函数
preEmit:在actions触发事件前调用。它从调用action的地方接受一个参数。如过preEmit有返回,返回值就会作为shouldEmit的参数,追加进原有的参数中。
shouldEmit:在preEmit后,action触发事件前调用。默认返回true,会让action正常触发event。如果你需要检查action接收的参数,你可以重写这个函数,看是否需要触发event。
Actions.statusUpdate.preEmit = function(){ console.log(arguments)};
Actions.statusUpdate.shouldEmit = function(value){
return value > 0;
}
Actions.statusUpdate(0);
也可以在定义action的时候就将这两个函数传进去
var actions = Reflux.createAction({
preEmit: function(){},
shouldEmit: function(){}
});
六、Reflux.ActionMethods
如果你有一些方法希望所有的action都能用,你可以扩展Reflux.ActionMethods对象,在action创建时,就会被掺进去
Reflux.ActionMethods.exampleMethod = function(){console.log(arguments)};
Actions.statusUpdate.exampleMethod('arg1');
//should output: 'arg1'