我正在使用通用启动器作为骨干。
当我的客户端启动时,它从localStorage读取有关用户信息的令牌。
@Injectable()
export class UserService {
foo() {}
bar() {}
loadCurrentUser() {
const token = localStorage.getItem('token');
// do other things
};
}
一切正常,但是由于服务器渲染,我在服务器端(终端)得到了这一点:
例外:ReferenceError:未定义localStorage
我从ng-conf-2016-universal-patterns中得到了使用依赖注入解决此问题的想法。但是那个演示真的很老。
说我现在有两个文件:
main.broswer.ts
export function ngApp() {
return bootstrap(App, [
// ...
UserService
]);
}
main.node.ts
export function ngApp(req, res) {
const config: ExpressEngineConfig = {
// ...
providers: [
// ...
UserService
]
};
res.render('index', config);
}
现在,他们使用相同的UserService。有人可以给出一些代码来解释如何使用不同的依赖注入来解决这个问题吗?
如果有比依赖注入更好的方法,那也很酷。
更新1我正在使用Angular 2 RC4,我尝试了@Martin的方法。但是即使我导入了它,它仍然在下面的终端中给我错误:
终端(npm启动)
/my-project/node_modules/@angular/core/src/di/reflective_provider.js:240抛出新的reflective_exceptions_1.NoAnnotationError(typeOrFunc,params); ^错误:无法解析'UserService'(Http,?)的所有参数。确保所有参数都用Inject修饰或具有有效的类型注释,并且'UserService'用Injectable修饰。
终端(npm run watch)
错误TS2304:找不到名称“ LocalStorage”。
我想它在某种程度上与LocalStorage
from angular2-universal
(虽然我没有使用import { LocalStorage } from 'angular2-universal';
)重复,但是即使我尝试将我的更改为LocalStorage2
,仍然无法正常工作。
同时,我的IDE WebStorm也显示红色:
顺便说一句,我找到了import { LocalStorage } from 'angular2-universal';
,但不确定如何使用它。
更新2,我更改为(不确定是否有更好的方法):
import { Injectable, Inject } from '@angular/core';
import { Http } from '@angular/http';
import { LocalStorage } from '../../local-storage';
@Injectable()
export class UserService {
constructor (
private _http: Http,
@Inject(LocalStorage) private localStorage) {} // <- this line is new
loadCurrentUser() {
const token = this.localStorage.getItem('token'); // here I change from `localStorage` to `this.localStorage`
// …
};
}
这解决了UPADAT 1中的问题,但是现在终端出现错误:
例外:TypeError:this.localStorage.getItem不是一个函数
更新以获取较新版本的Angular
OpaqueToken
被InjectionToken
具有相同功能的方式所取代-除了它具有InjectionToken<T>
用于更好地进行类型检查和推断的通用接口之外。
原始答案
两件事情:
您需要做的是为localStorage注入一个适配器,该适配器将同时适用于浏览器和NodeJS。这也将为您提供可测试的代码。
在local-storage.ts中:
import { OpaqueToken } from '@angular/core';
export const LocalStorage = new OpaqueToken('localStorage');
在您的main.browser.ts中,我们将从您的浏览器注入实际的localStorage对象:
import {LocalStorage} from './local-storage.ts';
export function ngApp() {
return bootstrap(App, [
// ...
UserService,
{ provide: LocalStorage, useValue: window.localStorage}
]);
然后在main.node.ts中,我们将使用一个空对象:
...
providers: [
// ...
UserService,
{provide: LocalStorage, useValue: {getItem() {} }}
]
...
然后,您的服务会注入以下内容:
import { LocalStorage } from '../local-storage';
export class UserService {
constructor(@Inject(LocalStorage) private localStorage: LocalStorage) {}
loadCurrentUser() {
const token = this.localStorage.getItem('token');
...
};
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句