我们有一个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)都会触发其呈现。
答案 0 :(得分:2)
在应用程序路由beforeModel
挂钩中执行重定向。
服务init
钩子不合适。
最好通过应用程序路由beforeModel
钩子在您的服务上调用自定义方法。
也许看看ember-simple-auth的mixins是如何工作的。
答案 1 :(得分:0)
Ember的beforeModel
钩子就能够阻止UI呈现,因此您可以做自己想做的事情。
但是,如果您正在执行jQuery Ajax调用,则需要确保在挂钩中返回了符合规范的Promise。 jQuery历史上不会返回这种类型的Promise(尽管这取决于您的jQuery版本和您调用ajax iirc的方式)。值得检查,因为您所描述的行为符合退还的承诺