Tod*_*ter 2 initializer ember.js ember-simple-auth
在我的EmberJS应用程序中,我有一个当前的用户初始化程序,它将用户注入所有控制器,路由和视图.它在登录时效果很好.我需要同步加载当前用户对象,这样我就可以立即检查一些用户权限.
这是我的初始化程序:
App.CurrentUserInitializer - Ember.Initializer.extent({
name: 'current-user',
after: 'authentication',
initialize: function(container, app) {
var store = container.lookup('store:main');
app.deferReadiness();
store.find('user', 'me').then(function (user) {
app.register('session:user', user, {instantiate: false});
_.forEach(['route', 'controller', 'view'], function (place) {
app.inject(place, 'currentUser', 'session:user');
});
app.advanceReadiness();
}).catch(function () {
app.advanceReadiness();
});
}
});
Run Code Online (Sandbox Code Playgroud)
这对我来说是崩溃的,是在登录期间.应用程序启动时,将运行初始化程序,但/users/me路径返回401错误.如果我没有捕获错误和advanceReadiness,则启动暂停.通过捕获错误,应用程序启动,但登录后初始化程序不会再次运行,因此不会加载当前用户.
我有什么选择?我不能使用@ marcoow推荐的向Session添加计算属性的方法,因为我需要在启动时加载用户.
我已经尝试强制将IndexRoute上的用户对象加载为hack,但这似乎不起作用.
任何提示都表示赞赏.
我注册了一个属性为null 的session:current对象user.这将注入controllers和routes(不确定注入内部视图是一个好主意).
所以在启动时,这user是未知的,但用户查找是在路由器比application路由深入之前完成的,根:
在路径的beforeModel钩子中application,您将加载当前用户.然后:
this.set('session.user', model)error钩子application,在这种情况下你必须检查原因,如果401那样你可以将用户重定向到登录路线this.transitionTo('login')session如果你有401这样的话,不要忘记设置一个标志,以便transitionTo我们的用户查找beforeModel不会再次发生,直到我们到达login路线
用于加载会话用户并初始化它的代码可以放在该session:current对象中,以便您可以从application路由或login控制器中调用它.
这是我的session初始化程序(不完全像我解释的那样,但加载到初始化程序中,因此更接近你所做的).我使用了一个session模型/session/current,然后我做了,然后有一个用户(或没有)具有正确的ID me,然后不会使该商店加载具有另一个ID的相同用户,因此具有两倍于2的相同用户不同的记录:
app/models/session.js:
import DS from 'ember-data';
import Ember from 'ember';
export default DS.Model.extend({
user: DS.belongsTo('user'),
isAuthenticated: Ember.computed.bool('user.isClaimed')
});
Run Code Online (Sandbox Code Playgroud)
app/initializers/session.js:
import Ember from 'ember';
export default {
name: 'session',
after: 'store',
initialize: function (container, app) {
var store = container.lookup('store:main'),
sid = Ember.$.cookie('sid');
// used to register a session
var register = function (session) {
app.register('session:main', session, {instantiate: false});
app.inject('route', 'session', 'session:main');
app.inject('controller', 'session', 'session:main');
};
// used to create a new session and trigger the backend to get details about it
// useful if the server is able to give an existing session while the browser doesn't know about it
// with external providers for example
var newSession = function () {
var session = store.createRecord('session');
// be sure to wipe out any invalid session ID
Ember.$.removeCookie('sid');
register(session);
return session.save().then(function (model) {
// if we got a valid new session, save its ID
Ember.$.cookie('sid', model.get('id'));
}).catch(function () {
Ember.debug('error saving new session: ' + Array.prototype.join.call(arguments, ', '));
});
};
// overall logic ==================
app.deferReadiness();
if (sid) {
// try to load the existing session
store.find('session', sid).then(function (model) {
register(model);
app.advanceReadiness();
}).catch(function () {
// there was a cookie for the session but it might have expired or the server invalidated it
Ember.debug('error loading session: ' + Array.prototype.join.call(arguments, ', '));
newSession().finally(function () {
app.advanceReadiness();
});
});
}
else {
// we don't have any trace of a session, let's just create a new one
newSession().finally(function () {
app.advanceReadiness();
});
}
}
};
Run Code Online (Sandbox Code Playgroud)
app/router.js:
import Ember from 'ember';
var Router = Ember.Router.extend();
Router.map(function () {
this.resource('session', {path: '/'}, function(){
this.route('login');
this.route('logout');
});
});
export default Router;
Run Code Online (Sandbox Code Playgroud)
app/templates/application.hbs(作为例子):
<h2 id='title'>Welcome to my app</h2>
{{#if session.isAuthenticated}}
<a {{action 'session.logout'}}>Logout</a>
{{else}}
{{#link-to 'session.login'}}Login{{/link-to}}
{{/if}}
{{outlet}}
Run Code Online (Sandbox Code Playgroud)
然后在登录控制器中,当用户实际登录时,服务器将返回session模型,并将用户链接到该模型,因此Ember绑定魔法将只更新会话对象.