我會註冊一個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')
});
應用程序/初始化/ 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();
});
}
}
};
應用程序/ 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;
應用/模板/ 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}}
然後一旦在登錄控制器中,當用戶實際登錄時,服務器將返回session
模型,用戶鏈接到該模型,因此Ember綁定魔術只會更新會話對象。
@華孚你有代碼示例可以顯示嗎?僅供參考 - 我使用的是ember-simple-auth,每當我在應用程序路徑上使用beforeModel時,即使返回履行的承諾,啓動也會停止。 – ToddSmithSalter 2014-09-23 17:43:15
啊,如果你正在使用'ember-simple-auth',那麼你應該在你的問題中說出它,因爲我不確定它是如何工作的,但肯定會使我的答案的某些部分失效。 我會添加一個示例,但它只是沒有簡單驗證。我聽說過簡單的身份驗證,但沒有使用它,所以不能舉一個例子。是的,在'beforeModel'掛鉤中放置承諾的目標是暫停路由器,也許這是簡單的認證,以某種方式暫停啓動,但通常一旦承諾完成,它應該繼續啓動 – Huafu 2014-09-24 00:03:44
@ToddSmithSalter,剛剛更新東西使用初始化;-) – Huafu 2014-09-24 01:43:03