2016-07-21 134 views
0

我有以下Javascript文件,我想導入到我的Angular 2項目中,而無需在Typescript中重新編寫整個內容。Angular 2 - TypeError:無法讀取未定義的屬性'createMessage'

當一切都正確綁起來,我得到以下錯誤...

「EXCEPTION:類型錯誤:未定義無法讀取屬性‘的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(); 
} 
} 
+0

你在哪一行得到錯誤?它看起來並不像你實際上在任何地方調用'SystemFactory.createMessage()' –

+0

這個調用來自我的「home.component.ts」文件,我添加了它。對於後面的用例,一切正常,但是一旦我在它打破的js中引入了「myApplication」對象。 – Daz

+0

我的直覺是問題出在.d.ts文件中,但我不確定解決方案。 – Daz

回答

0

你沒有任何出口出來applicationAPI的。 JS,所以你不能從它進口任何東西。當你import * as myApp from "myApplicationAPI";你沒有得到你認爲你得到的。

你的第一本能可能是導出myApplication,但你應該導出類和接口,而不是實例。讓Angular的依賴注入器處理實例。

我推薦的模式更像是這樣的:

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編譯器用作參考,說的是「相信我,有些東西看起來像這樣」,比如當你想讓你的打字稿與一個JS庫連接時。該庫仍然必須在.d.ts文件之外的其他地方定義。 你放入.d.ts文件的任何內容都不會被瀏覽器執行,甚至被瀏覽器看到。如果Message僅在.d.ts文件中定義,那麼您不能使用new Message,因爲在JavaScript在瀏覽器中運行的那一天結束時,將不會有任何Message的定義。

+0

我理解這種方法,但是,我的目標是不重寫任何應用程序API.js到應用程序API.ts中,而是從我的ts文件中使用它...是不是從我的「home.component .ts「來做到這一點?對我來說,看起來很奇怪,你不能僅僅將js文件添加爲「reference \ import」並將代碼添加到代碼中。這裏的問題是applicationAPI.js中「myApplication」的作用域丟失了,對吧?只是試圖瞭解這個過程的真實行爲,並沒有從我能找到的很多高質量的例子。 – Daz

+0

您可能可以編寫描述所有applicationAPI.js的行爲和屬性的.d.ts,然後在applicationAPI.js的底部添加一行:'window.myApp = myApplication;'。 .d.ts還需要聲明該接口存在於Window對象上。那麼你不需要導入任何東西來訪問你的ts中的'window.myApp'。這就是jQuery如何與邊打字一起使用(老實說,這和Angular沒有關係)。 –

+0

將以下內容添加到我的d.ts文件中... 導出界面窗口{0} {0} {0} myApplication:any; } 在「home.component.ts」中產生以下構建錯誤: 「Property'myApplication'在類型'Window'上不存在。」當我添加以下行... 「if(typeof window.myApplication ===」undefined「){}」 – Daz

相關問題