【问题标题】:Retrying request from Ember Data重试来自 Ember 数据的请求
【发布时间】:2016-07-12 09:02:51
【问题描述】:

我有一个带有 rails 后端的 ember 应用程序。

我有一个 Rails 可以返回的特定错误 (401),我希望 Ember 捕获并采取行动。在这种情况下,我想执行一个自定义方法(本质上修改请求 cookie),然后再次发出请求。

现在我在顶级路由器上发现了这个错误,并强制使用 window.location.reload() 重新加载整个应用程序。显然,这是一个可怕的 hack。我无法让 router.refresh() 工作,但无论如何这仍然是一个 hack。

理想情况下,我会在离适配器更近的地方捕捉到这一点,这样我就可以对其采取行动。也许我可以通过覆盖handleResponse() 在适配器级别捕获它,但是我将如何从那里重试请求?

http://emberjs.com/api/data/classes/DS.RESTAdapter.html#method_handleResponse handleResponse 确实传递了 requestData,但我需要一些方法来在适配器方法的上下文中执行请求,对吧?

【问题讨论】:

  • 我猜你的服务器在用户不被授权发出请求时返回 401,对吗?如果是,请说明您如何处理授权:您使用 ember-simple-auth 还是其他方式?
  • 我推出了自己的身份验证解决方案。我将一些用户元数据存储在本地存储中。此外,Rails 还维护一个会话。当 rails 会话已过期而本地存储尚未过期时,就会出现此问题。这种设计绝对不是最好的解决方案(我想我最终会移除本地存储部分),但现在它就是这样工作的。

标签: ember.js ember-data


【解决方案1】:

好吧,你可以在应用程序路由中处理这个错误(我做了什么):

error: function (error, transition) {
 /**
  * Code below may vary depending on your server's response format
  */
  if (error.errors !== undefined) {
    for (var i = 0; i < error.errors.length; i++) {
      if (error.errors[i].status !== undefined) {
        if (parseInt(error.errors[i].status) === 401) {
          transition.abort(); //this line may not be needed in last versions, I'm not sure
          //Do what should be done, redirect to authentication for example
          //transition.retry(); should work too
          break;
        }
      }
    }
  }
}

它可能看起来“级别太高”,但这是您在 ember 中处理错误的方式。前段时间写了一篇post关于错误处理的文章,有兴趣的可以看看。 当然你可能想扩展一个适配器来处理错误,但我不建议这样做。首先,您将无法访问适配器方法中的路由/控制器。其次,它不是“余烬之道”。适配器应该返回一个promice,如果出现错误会被拒绝,并且不应该以任何其他方式处理错误。

【讨论】:

  • dpaste.com/19PTY4N 你的代码也可以这样写。更多修饰方式。
  • 这与我正在做的非常接近,但它有很大帮助。我能够删除 window.location.reload() 并使用 transition.abort();过渡.重试();让我想要的页面重新加载工作。我仍然无法在需要时触发错误。如果我在出现错误的页面上并在浏览器中单击“重新加载”,则会触发错误。但是,如果我单击切换到另一条路线的站点上的链接,则会发生相同的错误,但不会被错误处理程序捕获。
  • @Jono 如果在模型挂钩期间发生错误,应通过错误操作处理。请注意,错误会冒泡,直到它被处理。例如,如果您有路由层次结构:应用程序/用户/用户,则错误可能由用户路由或用户路由或应用程序路由处理。这意味着如果您在用户路由上定义了错误操作,ember 可能不会调用应用程序路由的错误操作。
  • 像你一样,我在应用程序控制器中捕捉到了这个。但它仍然只捕获第一次 - 当应用程序加载时。第二次(路由之间的转换)错误被抛出它没有捕获。我尝试将错误操作移动到较低的路线,并且行为是相同的。我已经在每条路线上都抓住了,行为是一样的。最具体的路线捕获,但只有一次。
  • @Jono 您是否尝试删除 transition.abort()?在最新的 ember 版本中,我遇到了类似的问题并删除了该行已修复的错误
【解决方案2】:

如果路由的模型钩子 get 被拒绝,它会调用错误方法

您可以制作一个 mixin 并将其包装到您的路线中。

import RouteMixin from 'xx/mixins/route';

Ember.Route.extend(RouteMixin, {

})

并在 RouteMixin 中添加一个动作

error: function() {          
   // this.transitionTo('/not-found');
}

错误参数。

  • 服务器响应
  • 过渡类
  • 路线相关信息

您可以更改请求参数并重新路由。

【讨论】:

  • 是的,这正是我现在正在做的事情。但它的水平太高了。我试图在数据层中更透明地处理这个问题,而不必重新加载页面。这基本上破坏了单页应用程序和我所有的单元测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-26
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多