0

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

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

有没有办法让 RoutebeforeModel()方法阻止服务器调用的结果?我尝试在super.beforeModel()处理了 ajax 回调之后才显式调用,但 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)似乎会触发它们的渲染。

4

2 回答 2

2

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

也许看看ember-simple-auth的 mixin 是如何工作的。

于 2019-03-25T17:56:47.873 回答
0

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

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

于 2019-04-03T09:27:03.160 回答