typescript - 在构造函数中设置的函数中使用 this 的属性时,编译的 JavaScript 代码给出未定义
问题描述
我正在开发一个原型,目标是用 TypeScript 中的 express 框架编写一个 web 服务,将其编译为 TS 并将其托管在 firebase 函数环境中。服务中的代码层是控制器层,目前也是业务规则的业务逻辑层。可能与 .Net 编写的 web 服务中看到的层几乎相同。通过使用 inversifyJS 框架的依赖注入,我将逻辑类注入到控制器中。
到目前为止的部分 TypeScript 代码:
@injectable()
export class Service1Controller extends ApiController implements IService1Controller {
public constructor(
@inject(TYPES.IService1Logic)
private service1Logic: IService1Logic
) { super() }
private fastGet(request: Request, response: Response) {
const original = request.query.text;
const changed = this.service1Logic.UpdateFastGet(original);
response.status(200).send(changed);
}
}
export interface IService1Logic {
UpdateFastGet(text: string): string;
}
@injectable()
export class Service1Logic implements IService1Logic {
UpdateFastGet(text: string): string {
console.log(`[Service1Logic/UpdateFastGet]: ${text}`);
text = `${text} -> service1[fastget]`;
return text;
}
}
这是(部分)控制器代码的编译输出
constructor(service1Logic) {
super();
this.service1Logic = service1Logic;
}
fastGet(request, response) {
const original = request.query.text;
const changed = this.service1Logic.UpdateFastGet(original);
response.status(200).send(changed);
}
使用 firebase 函数模拟器在本地测试代码时,我收到一个错误,即无法从 undefined 读取属性 service1Logic。所以这似乎是未定义的,我不知道为什么。
我还尝试隔离错误并使用下一个代码重现它:
@injectable()
export class Class1 extends baseClass implements Interface1 {
constructor(
@inject(TYPES.Interface2)
private class2: Interface2
) { super() }
PrintText(text: string): void {
const mutatedText: string = this.class2.MutateText(text);
console.log(mutatedText);
}
Addition(x: number, y: number): number {
return this.Sum(x, y);
}
}
export interface Interface2 {
MutateText(text: string): string;
}
@injectable()
export class Class2 implements Interface2 {
MutateText(text: string): string {
console.log(`Received text ${text}`);
return `${text} mutated`;
}
}
控制器编译的代码看起来几乎一样(当然命名除外)
let Class1 = class Class1 extends baseclass_1.baseClass {
constructor(class2) {
super();
this.class2 = class2;
}
PrintText(text) {
const mutatedText = this.class2.MutateText(text);
console.log(mutatedText);
}
Addition(x, y) {
return this.Sum(x, y);
}
};
当我运行这段代码(不是在模拟器中而是在节点中)时,我根本没有收到任何错误,似乎 PrintText 中的这个确实存在。我还将 tsconfig.json 内容从原始项目复制到我尝试隔离错误的项目中,也许它与那里的设置有关,但据我所知,情况并非如此。我被困在错误上,我无法弄清楚是什么导致了错误。有没有人遇到过这种问题或知道我该如何解决?
编辑:添加调用代码
对于原型代码,方法链接到路由。
app.get('/fastget', this.fastGet);
应用程序是 Express 类型:
this.app = express();
app 通过 ApiController 中的 getter 返回,然后添加到 firebase 的 onRequest 中:
const service1Controller: IService1Controller = container.get<IService1Controller>(TYPES.IService1Controller);
export const service1 = functionsEUWest1.https.onRequest(service1Controller.App);
这些是类型和容器对象:
类型.ts
let TYPES = {
//Controllers
IService1Controller: Symbol("IService1Controller"),
//BusinessLogics
IService1Logic: Symbol("IService1Logic")
}
export default TYPES;
反转配置文件
class ContainerConfig {
private _container: Container = new Container;
get Container() { return this._container };
private configureControllers(container: Container) {
container.bind(TYPES.IService1Controller).to(Service1Controller);
}
private configureBusinessLogics(container: Container) {
container.bind(TYPES.IService1Logic).to(Service1Logic);
}
constructor() {
this.configureControllers(this._container);
this.configureBusinessLogics(this._container);
}
}
export default new ContainerConfig().Container;
对于隔离错误的代码,这是调用代码:
const class1: Interface1 = container.get<Interface1>(TYPES.Interface1);
class1.PrintText("This text is");
const result = class1.Addition(2, 3);
console.log(`Sum of 2 and 3 is ${result}`);
这就是 TYPES 和容器对象的样子:
类型.ts
let TYPES = {
Interface1: Symbol("Interface1"),
Interface2: Symbol("Interface2")
}
export default TYPES;
加强.config.ts
const container = new Container();
container.bind(TYPES.Interface1).to(Class1);
container.bind(TYPES.Interface2).to(Class2);
export default container;
解决方案
在做了更多研究之后,似乎在将处理程序传递给 app.get 时,在处理程序中不再知道实现处理程序的类中的 this。用这方面的知识多搜索,发现了下一个话题:
使用 app.get(..) 路由后 Express JS 'this' 未定义
似乎可以对该方法调用 .bind 。解决方案是将其绑定到fastget:
app.get('/fastget', this.fastGet.bind(this));
一切正常。
推荐阅读
- bash - 在 dockerfile 中加载 2 个进程?
- angular - 角度选择元素的 ngModel 不正确
- c# - 事件流和事件溯源
- time-complexity - theta(1) 在 n 次的总和是 theta(log n base 2)
- vba - VBA
- MyString 语句在代码中的作用如何? - j - J中的每个前置副词
- javascript - 使用Angular ngModel在输入类型日期中格式化日期时间
- visual-studio - 如何覆盖 docker-compose.vs.debug.g.yml 中的 Visual Studio 容器工具调试器卷?
- javascript - 如何从 Firestore 中检索第一个和最后一个集合
- java - SparkJava:如何在 before() 过滤器中验证 OAuth 令牌?