如何在不渲染的情况下重定向Ember页面?

时间:2019-03-25 17:34:44

标签: ember.js ember-2.0.0

我们有一个Ember UI,我们正在将其移植到Single Sign-on提供程序。它位于服务器端功能部件标志的后面,这样,当该标志打开时,用户将被重定向到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)都会触发其呈现。

2 个答案:

答案 0 :(得分:2)

在应用程序路由beforeModel挂钩中执行重定向。 服务init钩子不合适。 最好通过应用程序路由beforeModel钩子在您的服务上调用自定义方法。

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

答案 1 :(得分:0)

自从Ember 1.x时代以来,

Ember的beforeModel钩子就能够阻止UI呈现,因此您可以做自己想做的事情。

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