Ember.js 登录后同步注入当前用户
在我的EmberJS应用程序中,我有一个当前用户初始值设定项,它将用户注入到所有控制器、路由和视图中。登录后效果很好。我需要同步加载当前用户对象,这样我就可以立即检查一些用户权限 这是我的初始值设定项:Ember.js 登录后同步注入当前用户,ember.js,initializer,ember-simple-auth,Ember.js,Initializer,Ember Simple Auth,在我的EmberJS应用程序中,我有一个当前用户初始值设定项,它将用户注入到所有控制器、路由和视图中。登录后效果很好。我需要同步加载当前用户对象,这样我就可以立即检查一些用户权限 这是我的初始值设定项: App.CurrentUserInitializer - Ember.Initializer.extent({ name: 'current-user', after: 'authentication', initialize: function(container,
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();
});
}
});
这对我来说是在登录过程中出现故障的。当应用程序启动时,初始值设定项运行,但/users/me
路由返回401错误。如果我没有捕捉到错误和先进性,引导就会停止。通过捕获错误,应用程序将启动,但在登录后不会再次运行初始值设定项,因此不会加载当前用户
我的选择是什么?我不能使用@Marcow推荐的向会话添加计算属性的方法,因为我需要在启动时加载用户
我曾尝试将用户对象强制加载到IndexRoute上,但这似乎不起作用
非常感谢任何提示。我将注册一个
会话:当前对象,其用户属性为空。这将被注入控制器
和路由
(不确定注入内部视图是否是个好主意)
因此,在启动时,用户
是未知的,但用户查找是在路由器深入到应用程序
路由之前完成的,根:
在应用程序
路由的beforeModel
钩子中,您将加载当前用户。然后:
- 要么您得到了用户,然后将其设置为this.set('session.user',model)
或者您将进入应用程序的错误
钩子
路径,在这种情况下,您必须检查原因,如果401
,则您可以将用户重定向到登录路径this.transition('login')
如果您获得了401
,请不要忘记在session
上设置一个标志,这样transition
将使用户在到达登录路径之前不会再次查找beforeModel
用于加载会话用户并对其进行初始化的代码可以放在会话:当前
对象中,以便您可以从应用程序
路由或登录
控制器调用它
例如,这是我的会话
初始化器(与我解释的不完全一样,但加载到初始化器中,因此更接近您所看到的内容)。我使用了一个会话
模型,这样我就做了/session/current
,然后让一个用户进入(或不进入)其中,该用户具有正确的id,而不是me
,这将使存储区用另一个id加载同一个用户,因此将同一用户作为两个不同记录的两倍:
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')
});
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();
});
}
}
};
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;
app/initializers/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')
});
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();
});
}
}
};
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;
app/router.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')
});
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();
});
}
}
};
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;
app/templates/application.hbs(例如):
欢迎使用我的应用程序
{{{#如果session.isAuthenticated}
注销
{{else}
{{{#链接到'session.login'}登录{{/链接到}
{{/if}
{{outlet}}
然后,一旦进入登录控制器,当用户实际登录时,服务器将返回会话
模型,并将用户链接到该模型中,因此余烬绑定魔法将只更新会话对象。@Huafu您有可以显示的代码示例吗?仅供参考-我使用的是ember simple auth,每当我在应用程序路径上使用beforeModel时,启动都会停止,即使返回了已履行的承诺。啊,如果您使用的是ember simple auth
,那么您应该在问题中告诉它,因为我不确定它是如何工作的,但它肯定会使我的部分答案无效。我将添加一个示例,但它没有简单的auth。我听说过SimpleAuth,但没有使用它,所以不能给出一个例子。是的,在beforeModel
钩子中加入承诺的目的是暂停路由器,可能是简单的身份验证以某种方式停止引导,但通常一旦承诺实现,它应该继续boot@ToddSmithSalter,刚刚使用initialiser更新;-)令人惊叹的。谢谢你的例子。抱歉,我已将问题标记为ember simple auth。下次我会说得更清楚。哦,我的错!没有注意标签!