effect说起来概念不难,但是初期接触还是要迷糊一阵子的
目的:
为了抽取组件中的多余动作,让组件更单纯,复用性更好
方法:
为了达到以上目的,我们要先分辨出,“多余”的动作是什么?—什么是多余的 什么就是effect
说具体点儿,就是组件中 调取后台service部分的代码。
因为如果我们将service写在组件中,就会将此代码的复用性降低了,比如你在其他项目还是想利用此组件,但是另一个组件的调用后台的名称或方法并不一致,导致了组件没办法直接复用。
而有了effect的理念,我们将service方法直接抽离出来,根本不在组件中体现,这样组件就是一个很笨的组件,功能只涉及自己的业务,其他的都不管了。
下面逐行分析一下代码用法:
官方示例是相当简洁的,下面我将详细扩展说明
比如 有以下代码
//一个type
static LOGIN= 'LOGIN';
//一个action
{
type: LOGIN,
payload: {
task
}
我们来开始写effects 其实是官方示例
@Injectable()
export class AuthEffects {
constructor(private http: Http,private actions$: Actions) { }
@Effect() login$ = this.actions$
//这里 我们监听了‘LOGIN’ action ,固定写法,只要其他地方dispatch ‘LOGIN’,这边就会自动执行啦,这也是为什么effect可以抽离组件方法的原因,只要这里监听了 其他地方只要调用就会执行这边的代码
.ofType('LOGIN')
// 转换成 action 的 payload 数据流,这个如果你本身数据格式就是payload格式 就不用写。
.map(toPayload)
//这里是重点:首先,你监听了LOGIN,一旦触发了LOGIN,这里立马开始执行switchMap,以上基本都是固定写法不用管
//但是,这个参数payload,是通过监听type,找到了你的专属此type的action,然后将其中的payload返回了回来,作为参数。它可能是一个值,或者一个对象,不过我们关心的是它是可以取出来的。
.switchMap(payload => this.http.post('/auth',payload.task)
// 下面是从服务器返回来的res了
//又是重点来了----后面的运行,意思是直接dispatch了,effect已经帮你写好了,你不用再写dispatch了,即----我们dispatch了LOGIN_SUCCESS,让整体state发生了变化
.map(res => ({ type: 'LOGIN_SUCCESS',payload: res.json() }))
// 失败的话 也是dispatch
.catch(() => Observable.of({ type: 'LOGIN_Failed' }))
);
}
如何运用呢?直接在某处写:
this.store.dispatch({ type: LOGIN,payload: { task });
总结
再捋一遍,store dispatch 了 ‘LOGIN’ action,effect 监听了此动作,则开始自动执行 switchMap 方法,将 payload 作为参数传递进去,开始从后台调取数据,返回值直接作为新的 action 的 payload , dispatch 出去,更改 store 的 state 。
这么做的理由
就是组件只是在dispatch action,而具体发生了什么,这个组件根本不关心。
这样做的好处
可以想象,你和队员合作,他可以独立去开发effect,你来写组件,你们的对接口就是action,具体实现已经分离。
说到底,这也体现了angular的大团队协作思维,虽然学习代价确实高了些。。。。
原文链接:https://www.f2er.com/angularjs/146158.html