2017-06-16 64 views
0

正如我從文檔中瞭解到的,Service基本上是一個單例對象,用於通過應用程序生命週期向其他對象提供服務。我有一個用戶管理服務,用於在用戶使用路由/users/login登錄後保存身份驗證令牌。但是轉換到另一個路由(例如/composer)導致服務實例被重​​新創建,因此它將丟失所有存儲的數據。這與這個事實相矛盾嗎?只要應用程序確實存在或者我在整個生命週期中有什麼錯誤的想法,它就應該存在?Ember.js在路由轉換時重新創建服務對象

我注射服務在我所有的路線如下:

authenticationService: Ember.inject.service('authentication-service'), 

該服務本身只是一組getter和setter:

import Ember from 'ember'; 

export default Ember.Service.extend({ 
    currentUser: undefined, 
    jwtToken: undefined, 
    // ================================================================================================================ \\ 
    // ================================================================================================================ \\ 
    // ================================================================================================================ \\ 
    setCurrentUser(user) { 
     this.currentUser = user ; 
    }, 
    getCurrentUser() { 
     return this.currentUser ; 
    }, 
    isLoggedIn() { 
     return Boolean(this.currentUser) ; 
    }, 
    getJwtToken() { 
     return this.jwtToken ? this.jwtToken : '' ; 
    }, 
    setJwtToken(jwtToken) { 
     this.jwtToken = jwtToken ; 
    } 
}); 

這裏是登錄令牌如何處理:

actions: { 
    onSubmitLoginForm() { 
     if (!this.validateLoginForm()) { 
      return ; 
     } 
     var self = this ; 
     Ember.$.post('login/', { 
      'username': this.controller.get('username'), 
      'password': this.controller.get('password'), 
      'email': this.controller.get('email'), 
     }, function(data) { 
      console.log(data) ; 
      if (data['success'] === 'Ok') { 
       self.get('authenticationService').setJwtToken(data['auth']['jwt']) ; 
       var user = self.get('store').createRecord('user', { 
        username: data['auth']['user']['username'], 
        email : data['auth']['user']['email'], 
        mongoId : data['auth']['user']['id']['$oid'], 
       }) ; 
       self.get('authenticationService').setCurrentUser(user) ; 
       self.transitionTo('home') ; 
       console.log('logged in') ; 
       console.log(self.get('authenticationService').getJwtToken()) ; 
       console.log(self.get('authenticationService').getCurrentUser()) ; 
       console.log(self.get('authenticationService').isLoggedIn()) ; 
      } else { 
       self.transitionTo('error') ; 
      } 
     }) ; 
    }, 
} 

我不是在尋找建議使用一些其他方式的持久性,如在dexedDB;我很樂意瞭解這件事實際上是如何運作的,所以任何解釋都會被讚賞。

+0

你的理解一般是正確的。這是您的服務還是來自附加組件?你如何檢測到服務正在被實例化?你過得怎麼樣? – mwp

+1

在您的服務方法中,您應該使用'get'和'set'來獲取和設置屬性。不幸的是,僅僅因爲屬性是「本地」並不意味着你可以避免這種情況。也許更新這些方法,看看你的問題是否仍然存在? – mwp

+0

@mwp試過了,沒有幫助。無論如何,我不認爲它在這裏是必要的,因爲Ember.Object的get和set方法是爲了數據綁定和我們在此不使用的觀察者。 – DarthPaghius

回答

2

是的,你理解它是正確的 - 服務是一個單獨的服務,我可以向你保證,服務在轉換之間保持其狀態。但要進行轉換,您必須使用link-to助手。如果您手動更改網址,則需要重新加載應用而不是轉換。而應用程序重新加載當然會導致狀態重置。您應該使用任何可用類型的存儲來在頁面重新加載之間保持狀態。它可能是本地存儲,會話存儲,餅乾等。

此外,在Ember我們不使用Ember對象上的代碼:this.currentUser = user ;。我們用this.set('currentUser', user);代替。否則Ember將無法重新渲染模板,更新計算的屬性並正常工作。

最後,您不應該從零構建auth解決方案。這是非常艱難和複雜的事情。相反,您可以使用ember-simple-auth插件並在其上構建身份驗證過程。它會容易得多,結果會更可靠。

+0

關鍵是使用'{{link-to}}'。好像我在應用程序的某些地方習慣了習慣使用html錨定標記。關於你的其他建議我相信,只要滿足確切的要求,使用和插件就是一件好事,否則它將是一個修改它的折磨過程。感謝您的回答。 – DarthPaghius