Reflux中文教程——action

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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‘

 

 


 

以上是关于Reflux中文教程——action的主要内容,如果未能解决你的问题,请参考以下文章

Reflux中文教程——概览

Reflux之Store

React/Reflux:使用装饰器将带有 mixin 的类转换为 ES6

在 React.createClass 中挂钩 Reflux 存储并以正确的方式触发操作

如何使用 Jest 测试 Reflux 动作

如何使用 Reflux 商店处理分层数据?