【问题标题】:Import and use untyped leaflet JS plugin with Typescript 2 in Angular 2 project在 Angular 2 项目中导入和使用带有 Typescript 2 的无类型传单 JS 插件
【发布时间】:2017-03-28 16:07:17
【问题描述】:

我在 Angular 2 应用程序中使用 LeafletJS 库。库本身运行良好,因为我已经包含了类型定义 (leaflet.d.ts),当然还有传单节点模块。

我正在尝试为传单库导入一个名为“leaflet-canvasicon”的插件,但没有可用的类型定义,因为每当我尝试包含它时它都是用 ES5 编写的,编译器很满意,但我在控制台收到以下错误:

leaflet-src.js:314
Uncaught TypeError: this.callInitHooks is not a function
    at Object.NewClass (http://localhost:2080/main.bundle.js:58716:8)
    at http://localhost:2080/main.bundle.js:77650:180
    at Object.<anonymous> (http://localhost:2080/main.bundle.js:77652:3)
    at __webpack_require__ (http://localhost:2080/inline.js:53:30)
    at Object.<anonymous> (http://localhost:2080/main.bundle.js:54476:18)
    at __webpack_require__ (http://localhost:2080/inline.js:53:30)
    at Object.<anonymous> (http://localhost:2080/main.bundle.js:54411:90)
    at __webpack_require__ (http://localhost:2080/inline.js:53:30)
    at Object.<anonymous> (http://localhost:2080/main.bundle.js:54600:70)
    at __webpack_require__ (http://localhost:2080/inline.js:53:30)

我想到了很多解决方案

  • 为插件创建一个新的类型定义 (leaflet-canvasicon.d.ts) 并使用 Typescript 中的命名空间声明合并功能,以便仍将插件用作 L.CanvasIcon

  • 使用打字稿重写插件,扩展namespace L中的现有接口。

  • 停止使用键入的“传单”,只需导入用 ES5 编写的节点模块,然后在 Angular 的 typings.d.ts 文件中添加 L 声明:declare var L: any;

但每次我遇到编译器问题。我想我做错了。如何包含插件,让编译器满意并能够将其用作L.CanvasIcon

这里是package.json 文件:

 "dependencies": {
        "@angular/common": "2.1.2",
        "@angular/compiler": "2.1.2",
        "@angular/compiler-cli": "2.1.2",
        "@angular/core": "2.1.2",
        "@angular/forms": "2.1.2",
        "@angular/http": "2.1.2",
        "@angular/platform-browser": "2.1.2",
        "@angular/platform-browser-dynamic": "2.1.2",
        "@angular/platform-server": "2.1.2",
        "@angular/router": "3.1.2",
        "@types/leaflet": "^1.0.36",
        "core-js": "^2.4.1",
        "leaflet": "^1.0.1",
        "leaflet-canvasicon": "^0.1.6",
        "leafletjs-canvas-overlay": "^1.0.1",
        "rxjs": "5.0.0-rc.1",
        "ts-helpers": "^1.1.2",
        "zone.js": "^0.6.26"
      },
      "devDependencies": {
        "angular-cli": "1.0.0-beta.19-3",
        "ts-node": "1.6.1",
        "tslint": "3.15.1",
        "typescript": "2.0.6",
        "typings": "^1.5.0"
      }
    }

【问题讨论】:

    标签: angular typescript leaflet typescript-typings


    【解决方案1】:

    这是与缺少输入无关的运行时错误。问题与leaflet 版本不匹配有关。

    似乎leaflet-canvasicon 是为旧版本的leaflet 设计的。尝试使用版本0.7.x 回退到leaflet

     "dependencies": {
            "@angular/common": "2.1.2",
            "@angular/compiler": "2.1.2",
            "@angular/compiler-cli": "2.1.2",
            "@angular/core": "2.1.2",
            "@angular/forms": "2.1.2",
            "@angular/http": "2.1.2",
            "@angular/platform-browser": "2.1.2",
            "@angular/platform-browser-dynamic": "2.1.2",
            "@angular/platform-server": "2.1.2",
            "@angular/router": "3.1.2",
            "@types/leaflet": "0.7.x",
            "core-js": "^2.4.1",
            "leaflet": "0.7.x", // note the change
            "leaflet-canvasicon": "^0.1.6",
            "leafletjs-canvas-overlay": "^1.0.1",
            "rxjs": "5.0.0-rc.1",
            "ts-helpers": "^1.1.2",
            "zone.js": "^0.6.26"
          },
          "devDependencies": {
            "angular-cli": "1.0.0-beta.19-3",
            "ts-node": "1.6.1",
            "tslint": "3.15.1",
            "typescript": "2.0.6",
            "typings": "^1.5.0"
          }
        }
    

    对于未来,您可以记住this.callInitHooks is not a function 是在将旧扩展加载到leaflet 版本后典型问题 >=1

    【讨论】:

    • 是的,它在回退到leaflet 0.7 版本后工作。但是仍然需要类型定义才能在与L.CanvasIcon相同的命名空间中使用它。
    • 您是如何管理使用插件所需的类型定义的?
    【解决方案2】:

    如果您需要在 typescript 中使用传单插件,请在传单之后导入此文件。

    declare module L {
        // plugins that extend Class i.e L.MyClass
        export let MyClass:any;
        // plugins that uses class factory i.e myClass
        export let myClass:any;
    
       //plugins that extend Control comes here i.e L.Control.Navbar
       export namespace Control {
          export let Navbar: any;
       }
       // plugins that have control factories come here i.e. L.control.navbar
      export namespace control {
         export let navbar: any;
      }
    
      //plugins that extend Layer comes here i.e L.Layer.NewLayer
       export namespace Layer {
          export let NewLayer: any;
       }
      // plugins that have layer factories come here i.e. L.layer.newLayer
      export namespace layer {
         export let newLayer: any;
      }
      //plugins that extend Handler comes here i.e. L.Handler.NewHandler
       export namespace Handler {
          export let NewHandler: any;
       }
      // plugins that have handler factories come here i.e. L.Handler.newHandler
      export namespace handler {
         export let newHandler: any;
      }
    }
    

    如果你愿意,你可以明确地使用类型。

    【讨论】:

    • 您好,如果您收到类似“typeerror: L.Control.LinearCore is not a constructor”的错误消息,您会怎么做?我已经用我的变量名添加了你的代码,但是如果我的插件需要一个构造函数,还需要一点吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2016-07-30
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    相关资源
    最近更新 更多