2016-09-02 30 views
0

內的服務有一些問題,現在叫我創建了一個服務使用LokiJS(​​)我的app.config內。問題調用的app.config

我知道在Angular中,你真的不應該試圖在應用程序啓動期間嘗試在配置部分使用服務,而是從堆棧溢出中拼湊的其他答案我已經能夠實際訪問服務,但是仍然遇到現在看來是LokiJS特有的問題。

下面是我服務的一個副本:

(function(){ 

angular.module('LocalStorage', []) 
    .service('localStorageService', [ 
    'Loki', 
    '$q', 
    function(Loki, $q) { 

     var self = this; 

     var db; 
     var localstorage; 

     self.initDB = function() { 
      var adapter = new LokiCordovaFSAdapter({"prefix": "loki"}); 
      // Store to a file localstorage.json 
      db = new Loki('localstorage.json', 
        { 
         autosave: true, 
         autosaveInterval: 1000, // 1 second 
         adapter: adapter 
        }); 

      // Testing purposes only 
        console.log('end of Init DB'); 
     }; 

     self.getLocalStorage = function() { 

      console.log('calling get local storage'); 

      return $q(function (resolve, reject) { 
       var options = {}; 

       console.log('inside the return'); 

       db.loadDatabase(options, function() { 
        console.log('right before call getcollection'); 
        localstorage = db.getCollection('localstorage'); 

        console.log('grabbed local storage collection'); 

        if (!localstorage) { 
        console.log('localstorage did not exist so MAKING NEW ONE'); 
        localstorage = db.addCollection('localstorage'); 

        } 

        resolve(localstorage.data); 
       }); 
      }); 
     }; 

     self.getFromLocalStorage = function(value) { 

      var returnValue = localstorage.findOne({key: value}); 

      return returnValue; 
     }; 

     self.addToLocalStorage = function(key, value) { 
      // Format record to be stored 
      var data = {'key': key, 'value': value}; 

      // Check if this 'key' already exists in localstorage 
      if (self.getFromLocalStorage(key)) { 
      console.log('ATTEMPTING TO UPDATE INSTEAD OF INSERT'); 
      // If it exists then run an 'update' 
      //var lokiValue = self.getFromLocalStorage(key)['$loki']; 
      var lokiValue = self.getFromLocalStorage(key); 

      // Replace with new value 
      lokiValue['value'] = value; 

      // Now update 
      localstorage.update(lokiValue); 
      } else { 
      console.log('ATTEMPTING TO INSERT INSTEAD OF UPDATE'); 
      // If key does not exist, insert 
      localstorage.insert(data); 
      } 
     }; 

     self.deleteFromLocalStorage = function(value) { 

      // Grab object that you are trying to delete 
      var obj = self.getFromLocalStorage(value); 

      localstorage.remove(obj); 
     }; 

     // TODO Should only be used for testing purposes 
     self.deleteDatabase = function() { 

     console.log('ATTEMPTING TO DELETE DATABASE'); 
     db.deleteDatabase(); 
     }; 

    }]); 
    })(); 

而且在app.config:

app.config([ 
    '$stateProvider', 
    '$httpProvider', 
    'jwtInterceptorProvider', 
    'localStorageServiceProvider', 
    function ($stateProvider, $httpProvider, jwtInterceptorProvider, localStorageServiceProvider) { 

     localStorageServiceProvider.$get().initDB(); 

     localStorageServiceProvider.$get().getLocalStorage() 
     .then(
         function (result) { 
       // Auth interception 
       console.log("INFO", 'Create auth interceptor'); 
       jwtInterceptorProvider.tokenGetter = function (jwtHelper) { 
        var token = localStorageServiceProvider.$get().getFromLocalStorage('token'); 
        return token; 
       }; 
       $httpProvider.interceptors.push('jwtInterceptor'); 
            }, 
           function (error) { 
               // handle errors here 
               console.log('Something crazy happened with grabbing collection, This should not happen.'); 
            } 
   ); 

    }]); 

所以基本上所發生的事情是,代碼永遠不會執行過去「的console.log( '在回報裏面');「日誌語句在localStorageService內的getLocalStorage()函數內。我從來沒有看到任何日誌出現,所以看起來好像「db.loadDatabase()」實際上甚至不會運行。

如果這是我很困惑,如何「initdb的()」函數getLocalStorage以前更正確地執行()被調用的情況。

我不知道這是否是因爲一些洛基依賴問題,即它不能夠正確的,因爲我試圖東西完全調用的app.config裏面這個功能,或者說進行訪問。

的原因,我甚至試圖從app.config中的這裏面的服務來運行這些功能,是因爲我希望能夠存儲正在通過JwtInterceptorProvider訪問令牌。

任何與此有關的幫助將不勝感激,我對Angular和Loki都很新穎,所以我確信這裏只是一個小問題,或者我缺少這個結構設置,這是不正確的。謝謝!

回答

2

服務不應該用$get()實例化,由於自然原因,它們不在config中可用,這只是打破了事情。他們不再是單身人士(除了這使得他們無法測試)。

localStorageServiceProvider.$get().initDB(); 

localStorageServiceProvider.$get().getLocalStorage() 

指的localStorageService兩個不同的實例。

這裏有幾個競爭條件。這裏的主要問題是localStorageService是異步的。如果沒有它被稱爲在配置或運行階段,在當應用程序已達到運行階段和$http被實例化,並開始發出請求,這段代碼

   jwtInterceptorProvider.tokenGetter = ...; 
      $httpProvider.interceptors.push('jwtInterceptor'); 

的時間問題,可能仍然無法執行。

沒有辦法「暫停」角的應用程序初始化,以解決應用程序範圍內的依賴性。

解決這個問題的第一種方法是使用路由器解析器,它應該從根狀態繼承,以確保它在每個狀態下肯定會觸發。

某些提供程序可以在服務實例化之後進行配置。如果在引導應用程序後配置它們可能會很有用。這會使保修失效,不保證這樣的黑客服務不會導致副作用。

app.config(($provide, $httpProvider, jwtInterceptorProvider, $stateProvider) => { 
    $stateProvider.state('root', { 
    abstract: true, 
    resolve: { init, 'initResolver' } 
    }); 
    ... 

    // don't even needed if initResolver is defined as a function in config 
    $provide.value($httpProvider); 
    $provide.value(jwtInterceptorProvider); 
}); 

app.factory('initResolver', (localStorageService, $httpProvider, jwtInterceptorProvider) => { 
    localStorageService.getLocalStorage()... 
    jwtInterceptorProvider.tokenGetter = ...; 
    $httpProvider.interceptors.push('jwtInterceptor'); 
}); 

第二種方法是推遲自舉過程。如果應用程序依賴性是非角度的,這可能是一個很好的選擇,就像在這種情況下一樣。由於Loki數據庫應該由應用程序本身可以重複使用,有利於重構localStorageService只使用現有對象(甚至有可能不會需要包裝它的方法)

var lsDb = new Loki(...); 
var ls; 

lsDb.loadDatabase(...,() => { 
    ls = lsDb.addCollection('localstorage'); 

    angular.module('app') 
    .constant('localStorageDb', localStorageDb); 
    .factory('localStorageService',() => { 
    return ls; 
    }); 

    angular.bootstrap(document, ['app']); 
})