在app.config中发出调用服务问题

时间:2016-09-02 22:13:52

标签: javascript angularjs dependencies lokijs

现在有些问题调用我创建的服务,在我的app.config中使用了LokiJS(http://lokijs.org/#/)。

我知道在Angular中你真的不应该尝试在app启动期间使用config部分内的服务,但是从堆栈溢出拼凑在一起的其他答案我已经能够实际访问该服务,但我仍然遇到现在看似特定的LokiJS问题。

以下是我服务的副本:

ControlTemplate.Triggers

app.config:

MouseLeave

所以基本上发生的事情是代码永远不会执行“console.log('返回'内部);”在localStorageService内的getLocalStorage()函数内部记录语句。我从来没有看到任何过去的日志出现,所以似乎“db.loadDatabase()”实际上从未被运行过。

如果是这种情况,我很困惑在调用getLocalStorage()之前如何正确执行“initDB()”函数。

我不确定这是否是因为某些Loki依赖问题导致无法正常访问它,因为我试图在app.config中调用此函数,或完全不同。

我甚至试图从app.config中的这个服务运行这些函数的原因是因为我希望能够存储通过JwtInterceptorProvider访问的令牌。

对此有任何帮助将不胜感激,我对Angular和Loki都很陌生,所以我确信这里只有一个小问题,我缺少了,或者我有这种结构设置的方式这是不恰当的。谢谢!

1 个答案:

答案 0 :(得分:2)

服务不应该使用$get()进行实例化,由于自然原因,它们在config中不可用,这只是打破了事情。他们不再是那些单身人士(除了这使得他们不可测试的事实)。

    localStorageServiceProvider.$get().initDB();

和这个

    localStorageServiceProvider.$get().getLocalStorage()

引用localStorageService的两个不同实例。

这里有几种竞争条件。这里的主要问题是localStorageService是异步的。无论是在配置还是运行阶段调用它,在应用程序达到运行阶段并且$http被实例化并开始发出请求时,这段代码

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

可能仍未执行。

没有办法'暂停'Angular app初始化来解决应用程序范围的依赖关系。

处理这个的第一种方法是使用路由器解析器,它应该从根状态继承,以确保它肯定会在每个状态上触发。

可以在服务实例化后配置一些提供程序。如果应该在引导应用程序之后配置它们可能很有用。这使保修失效,不能保证像这样的黑客服务不会造成副作用。

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

第二种方法是推迟自举过程。如果应用程序依赖项是非Angular,这可能是一个不错的选择,就像在这种情况下一样。由于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']);
})