【发布时间】:2017-11-09 23:41:17
【问题描述】:
JIT and AoT compilers 之间的不一致让我遇到了一些问题。最近困扰我的错误是Error: Can't resolve all parameters for IndexedDBCache。 IndexedDBCache 是一个依赖于string 参数的服务:
请注意,当我删除“受保护”属性时也会出现此问题!
// indexeddb-cache.ts
import { Injectable } from '@angular/core';
@Injectable()
export class IndexedDBCache {
constructor(protected databaseName : string) {}
}
我正在使用工厂来提供服务的版本:
// test-api.cache.factory.ts
import { IndexedDBCache } from '../indexeddb-cache/indexeddb-cache';
export function testIndexedDBCacheFactory() { return new IndexedDBCache('test'); }
// test-api.cache.ts
import { InjectionToken, Provider } from '@angular/core';
import { IndexedDBCache } from '../indexeddb-cache/indexeddb-cache';
import { testIndexedDBCacheFactory } from './test-api.cache.factory';
export const testIndexedDBCache = new InjectionToken<IndexedDBCache>('testIndexedDBCache');
export let testIndexedDBCacheProvider : Provider = {
provide: testIndexedDBCache,
useFactory: testIndexedDBCacheFactory
};
注意:这些文件必须根据func-in-providers-useFactory 和arrow-function-exports 进行拆分 - 不要问我为什么 =/
现在 AoT 编译器根本不喜欢这个 string 参数。我已经调查了这个问题,但只能找到对OpaqueToken 的引用(现在已被废弃并被InjectionToken<string> 取代)。我的代码现在应该是:
// test-api.cache.factory.ts
import { InjectionToken } from '@angular/core';
import { IndexedDBCache } from '../indexeddb-cache/indexeddb-cache';
const testIndexedDBCacheFactoryToken = new InjectionToken<string>('test');
export function testIndexedDBCacheFactory() { return new IndexedDBCache(testIndexedDBCacheFactoryToken); }
显然这不是编译,因为构造函数只允许string 参数。我对 InjectionTokens 或手头的 AoT 问题没有足够的知识来解决这个问题 - 有人对可行的构造提出建议吗?
有关我的代码和问题的更多上下文,请访问 angular/angular#17295。
我尝试过的事情:
- 删除
protected访问修饰符> 完全相同的错误仍然存在 - 删除字符串参数> 不是一个选项 - 它定义了服务
- 将工厂中的字符串参数替换为
InjectionToken<string>> InjectionToken 不是合适的参数
【问题讨论】:
-
constructor(protected databaseName : string) {}你不能这样做,因为这个类被标记为@Injectable Angular 会尝试注入它不能做的字符串 -
@Toxicable 不过在使用 JIT 时效果很好。是否有另一种基于字符串设置服务工厂的方法?
-
如果类没有
@Injectable()Angular 不会尝试注入它,这是你可以使用构造函数的唯一方法 -
它确实有
@Injectable()并且可以工作。我让它在 JIT 和业力中运行。 -
在 JIT 中运行与在 AOT 中运行不一样,所以说它在一个中工作并不意味着它应该在另一个中工作