2016-09-02 31 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']); 
})