2014-09-23 5 views
2

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(); 
     }); 
    } 
}); 

이 나를 위해 분해 :

여기에 내 이니셜입니다. 앱이 부팅 될 때 이니셜 라이저가 실행되지만 /users/me 경로는 401 오류를 반환합니다. 오류 및 advanceReadiness를 잡아 내지 않으면 부팅이 중단됩니다. 오류를 포착하여 앱이 부팅되지만 로그인 후 이니셜 라이저가 다시 실행되지 않으므로 현재 사용자가로드되지 않습니다.

내 옵션에는 어떤 것들이 있습니까? 부팅 할 때 사용자를로드해야하기 때문에 @ marcoow가 권장하는 Session에 계산 된 속성을 추가하는 방법을 사용할 수 없습니다.

해킹으로 IndexRoute에서 사용자 개체로드를 시도했지만 작동하지 않는 것 같습니다.

팁을 주시면 감사하겠습니다.

답변

5

user 속성이 null 인 session:current 개체를 등록하고 싶습니다. 그것은 controllersroutes에 삽입 될 것입니다 (뷰 내부에 주입하는 것이 좋습니다). 당신이 현재로드 것의 application 경로의 beforeModel 후크에서

:

그래서 부팅시 user은 알 수 있지만, 라우터가보다 깊은 application 경로, 루트되기 전에 사용자 조회 완료 사용자. 그런 다음 :

  • 중 하나는 사용자를 가지고 다음의 경우 401을 당신은 그것을
  • this.set('session.user', model)를 설정하거나 당신이 이유를 확인해야 할 것이 경우 application 경로의 error 후크에 갈 것이고, 당신은 로그인 경로로 사용자를 리디렉션 할 수 this.transitionTo('login')

당신이 transitionTobeforeModel 우리의 사용자 조회가 우리까지 다시 발생하지 않도록 할 것 401 그래서 가지고있는 경우 session에 플래그를 설정하는 것을 잊지 마세요 login 경로

에게 코드에 도달하는 세션 사용자를로드하고 application 경로 또는 login 컨트롤러에서 호출 할 수 있도록 해당 session:current 객체에 배치 될 수 초기화하는 데 사용합니다.

이것은 예를 들어 내 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 바인딩 마법은 세션 객체를 업데이트합니다.

+0

. @ Huafu 표시 할 수있는 코드 예가 ​​있습니까? 참고 - 나는 ember-simple-auth를 사용하고 있으며 응용 프로그램 경로에서 beforeModel을 사용할 때마다 성취 된 약속이 반환 된 경우에도 부팅이 중단됩니다. – ToddSmithSalter

+0

아,'ember-simple-auth'를 사용하고 있다면, 어떻게 작동하는지 확실하지 않기 때문에 질문에 말해야합니다.하지만 확실하게 내 대답의 일부분을 무효로 만들 수도 있습니다. 예제를 추가하겠습니다 만 단순 인증이 필요하지 않습니다. 간단한 인증에 대해 들었지만 사용하지 않았으므로 실제로 예제를 제공 할 수는 없습니다. 예,'beforeModel' 훅에 약속을하는 목적은 라우터를 멈추는 것입니다. 어쩌면 부팅을 멈추는 간단한 인증 일 수도 있지만 일반적으로 약속이 완료되면 부팅을 계속해야합니다. – Huafu

+0

@ToddSmithSalter, 지금 막 업데이트되었습니다. 초기화자를 사용하는 무언가 ;-) – Huafu