【问题标题】:How to redirect an Ember page without rendering?如何在不渲染的情况下重定向 Ember 页面?
【发布时间】:2019-03-25 17:34:44
【问题描述】:

我们有一个 Ember UI,我们将其移植到单点登录提供商。这是在服务器端功能标志后面,这样,当标志打开时,用户将被重定向到 SSO 提供程序登录门户,而当标志关闭时,用户仍可以通过 Ember 路由登录。

我通过调用 Ember Route beforeModel() 调用中的服务器端点来实现此功能。但是,由于这是一个异步调用,因此页面会在请求返回、处理结果和重定向浏览器之前继续呈现。因此,用户可以在被重定向到 SSO 门户之前简要地看到旧的登录表单。我希望用户在显示 SSO 门户之前只看到一个空白的浏览器窗口。

有没有办法让 Route beforeModel() 方法阻止服务器调用的结果?我尝试仅在处理 ajax 回调后才对 super.beforeModel() 进行显式调用,但 Ember 似乎并没有等到它完成后再继续渲染。

return Em.Route.extend(/** @lends application.LoginRoute# */{
    beforeModel: function() {
      var route = this;
      return Ember.$.ajax(
        '/ws/ssoEnabled',
        {'success': function(json) {
          Em.Logger.info("[LOGIN ROUTE] SSO Redirect information:", json);
          if (json.isSsoEnabled === true) {
            Em.Logger.info("[LOGIN ROUTE] Redirecting to", json.ssoRedirectUrl);
            window.location.replace(json.ssoRedirectUrl);
            return;
          }
          route._super.beforeModel();
        },
        'error': function(reason) {
          Em.Logger.error("SSO detection failed", reason);
        });
    },

(大致就是这样;有一些全局语法糖辅助方法可以抽象Ember.$.ajax 调用。)

模型加载是否会阻止渲染直到加载?我犹豫要不要尝试,因为登录页面没有定义模型,所以需要更多的新代码。

应用程序的结构有些奇怪。登录页面实际上是 Ember v2.4 上的一个单独应用程序,因此我可以在应用程序代码中的任何位置挂接,而不必担心破坏实际应用程序。我也尝试过连接到应用程序,并且只从服务器调用承诺解析内部调用Ember.Application.create() 方法。但是,加载登录页面组件(通过 RequireJS)似乎会触发它们的渲染。

【问题讨论】:

  • 我会将ajax调用包装在另一个promise中,并在重定向到外部页面之前使用transition.abort()(参见docs);如果不发生重定向,则 Promise 可以正常解析(并且可能调用 _super)。
  • 我后来发现route.beforeModel() 不一定在我们的 Ember 版本中定义,调用它可能会导致错误记录到控制台。 abort() 上的有趣提示,我将在今天晚些时候试一试。

标签: ember.js ember.js-2


【解决方案1】:

在应用程序路由 beforeModel 挂钩中进行重定向。 服务init 挂钩不是正确的位置。 最好从应用程序路由 beforeModel 钩子调用您的服务上的自定义方法。

也许看看ember-simple-auths mixins 是如何工作的。

【讨论】:

  • 好提示。我发现这个文档页面证明了你关于在路由中重定向的观点:guides.emberjs.com/release/routing/redirection 但是,我仍然得到表单渲染的屏幕闪烁。我仍然需要弄清楚如何阻止。我将使用新代码编辑我的问题。
【解决方案2】:

Ember 的 beforeModel 钩子从 Ember 1.x 时代就已经能够阻止 UI 渲染,因此可以为所欲为。

但是,如果您正在执行 jQuery Ajax 调用,则需要确保在挂钩中返回符合规范的 Promise。 jQuery 历史上没有返回那种类型的承诺(尽管这取决于你的 jQuery 版本和你调用 ajax iirc 的方式)。值得检查,因为您描述的行为符合返回的非承诺

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-10
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 2020-07-01
    相关资源
    最近更新 更多