【问题标题】:Angular 2 - TypeError: Cannot read property 'createMessage' of undefinedAngular 2 - TypeError:无法读取未定义的属性“createMessage”
【发布时间】:2016-08-06 00:50:35
【问题描述】:

我有以下 Javascript 文件,我想将其导入到我的 Angular 2 项目中,而无需在 Typescript 中重写整个内容。

当一切都正确绑定时,我收到以下错误...

“异常:类型错误:无法读取未定义的属性‘createMessage’”

这是我对应的文件...

applicationAPI.js

var myApplication = myApplication || {};

(function(myApplication) {

myApplication.Message = function() {
    this.m_messageContents = "New Message";
};

myApplication.Message.prototype.getApplicationMessageContents = function() {
    return this.m_messageContents;
};

myApplication.SystemFactory = (function(){
    var factory =        
    {
        createMessage: function() {
            return new myApplication.Message();
        }
    };
    return factory;
}());

}(myApplication));

applicationAPI.d.ts

declare module "myApplicationAPI" {

export interface Message {
    getApplicationMessageContents(): string;
}

export class SystemFactory {
    static createMessage(): Message;
}

}

奇怪的是,当 applicationAPI.js 使用相同的 applicationAPI.d.ts 文件时,我可以让它工作。

applicationAPI.js

(function() {

this.Message = function() {
    this.m_messageContents = "New Message";
};

this.Message.prototype.getApplicationMessageContents = function() {
    return this.m_messageContents;
};

this.SystemFactory = (function(){
    var factory =        
    {
        createMessage: function() {
            return new this.Message();
        }
    };
    return factory;
}());}());

您有什么想法还需要添加什么才能让这个场景起作用吗?这对我来说并不明显......

这是来电的来源...

home.component.ts

import { Component, OnInit } from '@angular/core';
import * as myApp from "myApplicationAPI";
@Component({
moduleId: module.id,
selector: 'app-home',
templateUrl: 'home.component.html',
styleUrls: ['home.component.css']
})
export class HomeComponent implements OnInit {
title: string;

constructor() {}
ngOnInit() {
this.title = myApp.SystemFactory.createMessage().getApplicationMessageContents();
}
}

【问题讨论】:

  • 你在哪一行得到错误?看起来你实际上并没有在任何地方打电话给SystemFactory.createMessage()
  • 呼叫来自我的“home.component.ts”文件,我已经添加了它。后面的用例一切正常,但是一旦我在 js 中引入“myApplication”对象,它就会中断。
  • 我的直觉是问题出在 .d.ts 文件中,但不确定解决方案。
  • .d.ts 文件应该不会影响您的应用程序的实际运行方式。其中没有操作代码。
  • 所以你的解决方案是?

标签: javascript typescript angular


【解决方案1】:

您没有从 applicationAPI.js 中导出任何内容,因此您无法从中导入任何内容。当你 import * as myApp from "myApplicationAPI"; 时,你并没有得到你认为你得到的东西。

您的第一反应可能是导出myApplication,但您应该导出类和接口,而不是实例。让 Angular 的 Dependency Injector 处理实例。

我会推荐一个更像这样的模式:

applicationAPI.ts

import Injectable from '@angular/core';
// either define Message in this file or import it as well
// if you define it here, export it as well

@Injectable
export class Api {
  static createMessage(): Message {
    return new Message();
  }
}

home.component.ts

import Api from 'applicationAPI';
...
  constructor (private api: Api) {...}

假设您的引导调用看起来像 bootstrap(HomeComponent) 它应该更改为

import Api from 'applicationAPI';
...
bootstrap(HomeComponent, [Api]);

这将确保每次注入 Api 时,它都是同一个实例,尽管如果类上的所有方法都是静态的,这对您来说可能无关紧要。

.d.ts 文件被 typescript 编译器用作参考,它会说“相信我,有些东西看起来和行为都像这样”,例如当你希望你的 typescript 与 JS 库交互时。该库仍然必须在.d.ts 文件之外的其他地方定义。 您放入.d.ts 文件中的任何内容都不会执行,甚至不会被浏览器看到。 如果Message 仅在.d.ts 文件中定义,那么您不能使用new Message,因为在当 javascript 在浏览器中运行的那一天结束时,Message 是什么将没有任何定义。

【讨论】:

  • 我理解这种方法,但是,我的目标是不将任何 applicationAPI.js 重新写入 applicationAPI.ts,而是从我的 ts 文件中按原样使用它......有没有从我的“home.component.ts”如何做到这一点?对我来说,您不能只将 js 文件添加为“引用\导入”并远离代码,这对我来说似乎很奇怪。这里的问题是 applicationAPI.js 中“myApplication”的范围丢失了,对吧?只是想了解这个过程的真实行为,我找不到很多高质量的例子。
  • 你可以写一个 .d.ts 描述所有 applicationAPI.js 的行为和属性,然后在 applicationAPI.js 的底部添加一行:window.myApp = myApplication;。 .d.ts 还需要声明此接口存在于 Window 对象上。然后你就不必导入任何东西来访问你的 ts 中的window.myApp。这就是 jQuery 可以与打字稿一起使用的方式(老实说,这与 Angular 的这种方法无关)。
  • 将以下内容添加到我的 d.ts 文件中... 导出界面窗口 { myApplication: any;在“home.component.ts”中产生以下构建错误“属性'myApplication'在类型'Window'上不存在。”当我添加以下行时...“if (typeof window.myApplication === "undefined"){}"
  • 试试export interface Window {...}。请注意,Window 是大写的。
  • 这两种组合都不起作用,同样的错误。这与我导入模块的方式有关吗?
猜你喜欢
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
  • 2016-10-19
  • 1970-01-01
  • 2014-11-29
  • 2018-10-29
  • 2021-07-21
相关资源
最近更新 更多