Angular 2 - TypeError:无法读取未定义的属性“createMessage”

时间:2016-07-21 20:40:15

标签: javascript typescript angular

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

如果一切正确,我会收到以下错误...

“EXCEPTION:TypeError:无法读取未定义的属性'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();
}
}

1 个答案:

答案 0 :(得分:0)

您没有从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文件被打字稿编译器用作参考文件,说出"对我的信任,有些东西看起来像这样#34;例如,当您希望您的打字稿与JS库交互时。该库仍然必须在.d.ts文件之外的其他位置定义。 您放入.d.ts文件中的任何内容都不会被浏览器执行甚至被浏览器看到。如果Message仅在.d.ts文件中定义,那么您可以&#39 ; t使用new Message因为在浏览器中运行javascript的那一天结束时,我们不知道Message是什么的定义。