【问题标题】:How to declare a singelton in typescript如何在打字稿中声明单例
【发布时间】:2019-02-24 11:46:35
【问题描述】:

我想将现有库集成到我的打字稿项目中。我要声明和使用一个(外部)单例对象。

示例: 在 xyz.js 中,将声明以下对象:

var mxUtils = {
    /* some fancy code */
    findNode: function(node, attr, value)
    {
        // even more fancy code
        return node;
    }
};

在运行时,有一个全局单一的 mxUtils 实例。由于这是一个外部库,我不想在 typescript 中实现或重写整个库。

现在我试图声明这个单例,但我失败了。

我尝试了这段代码,将 Object 声明为全局变量。

Utils.d.ts:

declare interface ImxUtils { 
    findNode(node:any, attr:string, value:string):any;
}

declare var mxUtils: ImxUtils;

我的编译器对此完全满意,但是在运行时,mxUtils 是未定义的

main.ts:

// some fancy things
export class fancyComponent implements OnInit {
    // some magic here...
    var tmpNode = mxUtils.findNode(aNode, aString1, aString2);    
}

即使我的调试器列出了一个全局 mxUtils 对象。

谁能帮我解决这个问题?

请备注: * xyz.js 已被引用并存在。 例如

xyz.js

function mxEventObject(name)
{
//
}

mxEventObject.prototype.getName = function()
{
    return this.name;
};

Utils.d.ts

declare class mxEventObject {
    constructor(name: string);
    getName: () => string;
}

main.ts

export class fancyComponent implements OnInit {
    // some magic here...
    var tmpEvent = new mxEventObject(aSampleString);

}

将按预期工作。

由于有一个名为 mxUtils 的全局对象,但我无法在我的 fancyComponent 导出中访问该对象,我想存在范围问题。

【问题讨论】:

  • 为什么mxUtils 不是未定义的?它在哪里初始化? .d.ts 中的定义只是定义,它们告诉编译器该接口,更重要的是变量 exist 在运行时。它们如何存在不是编译器的工作。
  • 你在使用 angular 吗?
  • 你需要将 xyz.js 添加到 .angular-cli.json 中的脚本列表中
  • 这个对象确实在运行时存在,并且在运行时可以在我的javascript控制台访问,
  • 我已经测试了你的代码,它正在工作stackblitz.com/edit/angular-g9sy1v 检查你说你可以访问 mxUtils 对象抛出控制台的控制台,这意味着如果它是一个 js 库,它已经被加载

标签: angular typescript singleton mxgraph ambient


【解决方案1】:

在 Angular 中更好地中继 DI(依赖注入)系统来处理对象创建并将这些对象注入到组件中,您需要创建一个 Angular 服务并将该服务添加到 AppModule 组件装饰器中的提供者列表中。

mx-utils.service.ts

export class MxUtilsService {

  /* some fancy code */
  public findNode(node:any, attr:any, value:any) {
    // even more fancy code
    return node;
  }
}

app.module.ts

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ],
  providers: [MxUtilsService]
})
export class AppModule { }

app.compoennet.ts

import { Component } from '@angular/core';
import { MxUtilsService } from './mx-utils.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(private _mxUtilsService: MxUtilsService) {
    console.log(this._mxUtilsService);
    console.log(this._mxUtilsService.findNode({node:1},'node',1));
  }
}

在 appModule(root) 中添加到提供者列表的任何服务都被视为 singleton , MxUtilsService 将创建一个,并且当您注入另一个组件时将是同一个对象

stackblitz demo

为什么您的对象未定义,您需要将xyz.js 添加到脚本列表 在.angular-cli.json

【讨论】:

  • 这不是一个有用的选择,因为这是一个外部库,会经常更新。这就是我写的原因,我不想重写这个 xyz 库。
  • 已更新您需要包含 xyz.js 以在运行时捆绑的答案@Stefan
猜你喜欢
  • 1970-01-01
  • 2014-05-29
  • 2017-10-22
  • 2017-06-25
  • 2019-05-05
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
  • 1970-01-01
相关资源
最近更新 更多