【发布时间】: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