Dva: 前后端分离遇到的一些问题

Created on 3 Mar 2017  ·  7Comments  ·  Source: dvajs/dva

我这边的框架大概是这种写法

<App>{login && children || (<Login />)} </App>

所有的组件都是放到 App 的 children 里面。

每个 route 的初始化流程都是 app init -> child int 。这两个 init 都是通过调用 subscriptions 的 setup 事件。这两个 init 属于不同的 namespace

下面我遇到了几个问题:

  1. app init 跟 child init 执行实际上好像没有先后关系。实际上我是想 app init 成功之后,再去执行 child 的init

  2. app init 不成功, 需要 login 的时候,显示 login , 并执行相关逻辑 。 login 成功之后, child 可以显示,但是没有数据。 因为在 1 步骤里面 , child init 是失败的。 我不知道,该怎么让 login 成功之后,去执行 child 的 init

  3. 我的菜单,或者链接,基本上都是用的 history.push 操作,没有用 Link 。这样发现一个问题,点击浏览器后退的时候, 上一个页面没有刷新,如何能让页面强制刷新。因为,我当前 route 增加了一个申请,后退是到了 申请列表的 route ,我想在这个列表的 route 中显示新数据

  4. 从上面 3 个问题,基本都有一个问题,就是如何跨 namespace 调用 action。而且是不知道,你要调用的那个 action 属于哪个 namespace 的前提下。

  5. 以前前后端没分离前,页面跳转,有时候是通过后端直接 redirect 。现在我是通过后台反馈 模拟 302, 303 来指导前端去进行跳转。跳转一般是在 effects 里面才能决定的,但是 effects 里面没有 history 。后来,我直接用的 window.location.href 跳转。这种场景,有没有什么好的解决方案?

  6. 通过前端的跳转,(不是route页面的跳转),我发现一个问题,就是很容易出现 net::ERR_BLOCKED_BY_CLIENT 错误。网上查了很多,包括去 stackoverflow ,基本上都是说 chrome 插件的问题。我机器上也确实装了很多插件。但是我把所有的插件都禁用。基本也解决不了这个错误。这个是我在做 微信公众号 oauth2 验证时遇到的问题。另外,一个现象是,使用 hash history 发生 net::ERR_BLOCKED_BY_CLIENT 错误的次数远大于 browser history 。

  7. 延续6,oauth 验证的大致步骤是 本地 -> 远程 -> 本地。有时候本地跳远程,要多刷几次。远程跳本地成功之后,发现本地的 app 所有的 init 都不执行不管是 app init 还是 child init 。很无语 ...

还有好多问题,都是通过各种很烂的方式,暂时弥补过去了。

这里想请大神们给小弟一点指引 !

question

Most helpful comment

我也碰到楼主类似的问题。
1、执行顺序应该跟模型加载顺序有关。
2、我没有在setup里面发起请求申请,在组件的componentDidMount里面发起,可以保证登录后再执行child init

整个流程是
打开页面 -> 获取缓存token(后台/localstorage) -> 根据token获取账号
a: -> 成功 -> 执行初始请求
b: -> 失败 -> 呈现登录界面 -> 输入账号密码 -> 成功 -> 执行初始请求

All 7 comments

1.不清楚。
2.我并没有采用这种方式,登录成功后除了把用户信息放入model里,还把拥有的所有权限放到了localStorage里,每次访问路由时我都会拦截去判断他有没有这个路由的权限,如果实际上后端没有这个权限了,后端会返回401,我前端就提示未有权限或者登录失败,并用window.location.href 跳转到登录页面。
3.菜单用的antd,都是Link。
4.调用其他action,我的例子,在namespace为user的model里调用namespace为system里的.

yield put({ type: 'system/result',payload:{response, namespace:'user'} });
  1. window.location.href 这种方式可以的啊!给302页面做一个登录跳转连接之类的感觉没啥影响吧!
    6.没出现过。
    7.不懂,我的是每次访问路由组件去localstorage判断,然后用户去后端取数据时服务端判断,没权限对应处理。

可能在上级组件中不知道下级组件是什么,也不知道它的model是什么,可以反过来在下级组件的model里面take上级的某个action

我也碰到楼主类似的问题。
1、执行顺序应该跟模型加载顺序有关。
2、我没有在setup里面发起请求申请,在组件的componentDidMount里面发起,可以保证登录后再执行child init

整个流程是
打开页面 -> 获取缓存token(后台/localstorage) -> 根据token获取账号
a: -> 成功 -> 执行初始请求
b: -> 失败 -> 呈现登录界面 -> 输入账号密码 -> 成功 -> 执行初始请求

  1. 写到一个subscriptions里面, 在里面调用effect, effect里写app init 和child init.
  2. 让login操作更新child组件会用到的state, child会更新的, 如果不是纯函数, 就在componentWillReceiveProps做些操作.
  3. 用高阶组件的componentWillReceiveProps方法, 或者在subscriptions里订阅该路由变更事件
  4. 意思是用哪个model是调用参数决定的?写到一个model在里面判断呢

  5. ```
    import { routerRedux } from 'dva/router';

in effect

yield put(routerRedux.push('anyPathYouLike'));

@grunmin 谢谢,学习了

如何判断页面加载完成?
然后当页面完成后执行一些方法

在 dva 框架中 如何调用 componentDidMount 方法呢?

Was this page helpful?
0 / 5 - 0 ratings