gpt4 book ai didi

angular - 创建 AoT 兼容的服务工厂

转载 作者:太空狗 更新时间:2023-10-29 17:54:26 25 4
gpt4 key购买 nike

我正在尝试为缓存服务创建服务工厂。主要要求是每次都可以使用不同的字符串实例化单个服务。

最终结果将有多个缓存服务,每个服务由唯一的databaseName定义。每个缓存可以有一个或多个存储,也由唯一的storeName 定义。其他服务将能够使用这些商店:

mainCache                         = new Cache('main')
├── userStore = new Store(mainCache, 'user')
│ ├── userService
│ └── authenticationService

└── taskStore = new Store(mainCache, 'task')
└── taskService

fooCache = new Cache('foo')
└── barStore = new Store(otherCache, 'bar')

我目前的实现是这样的:

//indexeddb-cache.ts
import { Injectable } from '@angular/core';

@Injectable()
export class IndexedDBCache {
constructor(
protected databaseName : string
) {}
}

// indexeddb-store.ts
import { Injectable } from '@angular/core';
import { IndexedDBCache } from './indexeddb-cache';

@Injectable()
export class IndexedDBStore {
constructor(
protected database : IndexedDBCache,
protected storeName : string
) {}
}

服务是工厂化的:

// test-api.cache.factory.ts
import { IndexedDBCache } from '../indexeddb-cache/indexeddb-cache';
import { IndexedDBStore } from '../indexeddb-cache/indexeddb-store';

// factory functions for FactoryProviders as exports instead of inline:
// https://github.com/rangle/angular-2-aot-sandbox#func-in-providers-usefactory-top
export function mainIndexedDBCacheFactory() { return new IndexedDBCache('main'); }
export function userIndexedDBStoreFactory(testIndexedDBCache: IndexedDBCache) { return new IndexedDBStore(testIndexedDBCache, 'user'); }
export function taskIndexedDBStoreFactory(testIndexedDBCache: IndexedDBCache) { return new IndexedDBStore(testIndexedDBCache, 'task'); }

然后提供:

// test-api.cache.ts
import { InjectionToken, Provider } from '@angular/core';
import { IndexedDBCache } from '../indexeddb-cache/indexeddb-cache';
import { IndexedDBStore } from '../indexeddb-cache/indexeddb-store';
import { mainIndexedDBCacheFactory,
taskIndexedDBStoreFactory,
userIndexedDBStoreFactory } from './test-api.cache.factory';

// Caches

export const mainIndexedDBCache = new InjectionToken<IndexedDBCache>('mainIndexedDBCache');

export let mainIndexedDBCacheProvider : Provider = {
provide: mainIndexedDBCache,
useFactory: mainIndexedDBCacheFactory
};

// Stores

export const userIndexedDBStore = new InjectionToken<IndexedDBStore>('userIndexedDBStore');

export let userIndexedDBStoreProvider : Provider = {
provide: userIndexedDBStore, deps: [mainIndexedDBCache],
useFactory: userIndexedDBStoreFactory
};

export const taskIndexedDBStore = new InjectionToken<IndexedDBStore>('taskIndexedDBStore');

export let taskIndexedDBStoreProvider : Provider = {
provide: taskIndexedDBStore, deps: [mainIndexedDBCache],
useFactory: taskIndexedDBStoreFactory
};

在主模块中声明:

// test-api-module.ts
import { NgModule, ModuleWithProviders } from '@angular/core';
import { mainIndexedDBCacheProvider,
taskIndexedDBStoreProvider,
userIndexedDBStoreProvider } from './test-api.cache';

@NgModule({
imports: [], declarations: [], exports: []
})
export class TestAPIModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: TestAPIModule,
providers: [
mainIndexedDBCacheProvider,
userIndexedDBStoreProvider,
taskIndexedDBStoreProvider
]
};
}
}

最后在服务中使用:

//user-service/user.service.ts
import { Inject, Injectable } from '@angular/core';
import { IndexedDBStore } from '../../indexeddb-cache/indexeddb-store';
import { userIndexedDBStore } from '../test-api.cache';

@Injectable()
export class UserService {
constructor(
@Inject(userIndexedDBStore) protected cache : IndexedDBStore
) {}
}

使用 JIT 编译器时一切正常。当我尝试进行 AoT 编译时,我开始收到 警告:无法解析 y 中 x 的所有参数:(?)。对于缓存和存储服务的字符串参数,这将在 Angular v5.x 中成为一个错误。

我之前在这个问题中详细说明了我的问题:Tokenizing for AoT compilation .现在看起来使用字符串作为 @Injectable() 的参数对于 AoT 编译器来说是完全不可能的。是否有任何其他方法可以为使用我所描述的字符串初始化的服务创建工厂?

我在 this repository 中创建了一个可行的示例.检查 aot 分支和 npm install 然后 npm run build.prod.rollup.aot 应该就像那样工作。

最佳答案

根据用户@estus 和@Toxicable 的反馈,仅由Factory 实例化的类不应是@Injectable 本身。从 IndexedDBCacheIndexedDBStore 类中删除此标记将解决该问题。


Factory 也必须是特定的形式

export function mainIndexedDBCacheFactory() { return new IndexedDBCache('main'); }

此定义的其他迭代将不起作用。

export const mainIndexedDBCacheFactory = function() { return new IndexedDBCache('main'); };
export let mainIndexedDBCacheFactory = function() { return new IndexedDBCache('main'); };
export let mainIndexedDBCacheFactory = () => new IndexedDBCache('main');

export prefix is required即使定义与 Provider 在同一个文件中也是如此。

关于angular - 创建 AoT 兼容的服务工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44461657/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com