2013-08-24 62 views
0

使用TypeScript 0.9.1.1時,當試圖從另一個模塊/文件訪問靜態變量時,它未定義。TypeScript:在RequireJS中使用靜態變量AMD

示例代碼:

App.ts:

import Game = require('Game'); 

var game = new Game(); 

Game.ts:

import Grid = require('Grid'); 

class Game 
{ 
    public Grid: Grid; 
    public static Game: Game; 

    constructor() 
    { 
     Game.Game = this; 
     this.Grid = new Grid(); 
     this.Grid.SeeIfStaticWorks(); 
    } 
} 

export = Game; 

Grid.ts:

import Game = require('Game'); 

class Grid 
{ 
    public SeeIfStaticWorks() 
    { 
     var shouldNotBeUndefined = Game.Game; 
    } 
} 

export = Grid; 

調用this.Grid.SeeIfStaticWorks();前檢查Game.Game表明,它的定義:

http://j.mp/1dCY8Ec

但試圖從訪問它裏面SeeIfStaticWorks()當它是不確定的:

http://j.mp/1dCYISe

問題是:如何能夠從其他模塊訪問靜態變量?


更新:

使用跨模塊靜態變量(demo here)允許從一個文件上運行所有的代碼:

class Grid 
{ 
    public SeeIfStaticWorks() 
    { 
     console.log(Game.Game); 
     if (Game.Game) 
      alert('Instance is defined!'); 
     else 
      alert('Instance is undefined!'); 
    } 
} 

class Game 
{ 
    public Grid: Grid; 

    private static game : Game; 
    public static get Game() : Game 
    { 
     if (this.game == null) 
     { 
      this.game = new Game(); 
     } 

     return this.game; 
    } 

    constructor() 
    { 
     this.Grid = new Grid(); 
    } 
} 

var game = Game.Game; 

game.Grid.SeeIfStaticWorks(); 

如果使用相同的邏輯與AMD RequireJS的調用時,靜態變量未定義SeeIfStaticWorks()

個App.ts:

import Game = require('Game'); 

var game = Game.Game; 

game.Grid.SeeIfStaticWorks(); 

Game.ts:

import Grid = require('Grid'); 

class Game 
{ 
    public Grid: Grid; 

    private static game : Game; 
    public static get Game() : Game 
    { 
     if (this.game == null) 
     { 
      this.game = new Game(); 
     } 

     return this.game; 
    } 

    constructor() 
    { 
     this.Grid = new Grid(); 
    } 
} 

export = Game; 

Grid.ts:

import Game = require('Game'); 

class Grid 
{ 
    public SeeIfStaticWorks() 
    { 
     console.log(Game.Game); 
     if (Game.Game) 
      alert('Instance is defined!'); 
     else 
      alert('Instance is undefined!'); 
    } 
} 

export = Grid; 

回答

1

這是因爲,當文件Game.ts解析Game.Game沒有設置。你可以看到,在生成的JavaScript:

var Game = (function() { 
    function Game() { 
     Game.Game = this; 
     this.Grid = new Grid(); 
     this.Grid.SeeIfStaticWorks(); 
    } 
    return Game; 
})(); 

若要在導出的東西,你必須定義點設置它們的靜態變量可用(不是懶洋洋地在你的情況下)。所以:

class Game 
{ 
    public Grid: Grid; 
    public static Game: Game = new Game(); // set it outside the constructor 

    constructor() 
    { 
     this.Grid = new Grid(); 
     this.Grid.SeeIfStaticWorks(); 
    } 
} 

你可以看到生成的javascript:

var Game = (function() { 
    function Game() { 
     this.Grid = new Grid(); 
     this.Grid.SeeIfStaticWorks(); 
    } 
    Game.Game = new Game(); // Now this statement will execute when this javascript is parsed 
    return Game; 
})(); 

如何管理單身是一個單獨的討論。但我相信上面的代碼是足夠的。 (如果你想要一個真正的單身人士,你可以進行額外的檢查)。

+0

它不會以這種方式工作,因爲'SeeIfStaticWorks()'會在'Game.Game'實例化之前運行。我發佈了更接近我可能使用的代碼的更新。問題看起來可能與RequireJS有關。尼斯AngularJs/TS視頻順便說一句:) –

+0

因爲它不這樣工作,請你刪除答案?這將有助於更快獲得正確答案。 –

+0

看到我的其他答案 – basarat

0

以下與訂單無關的代碼有效。格前演示遊戲:

class Game 
{ 
    public Grid: Grid; 
    public static Game; 

    constructor() 
    { 
     Game.Game = this; 
     this.Grid = new Grid(); 
     this.Grid.SeeIfStaticWorks(); 
    } 
} 
class Grid 
{ 
    public SeeIfStaticWorks() 
    { 
     console.log(Game.Game); 
     if (Game.Game) 
      alert('Instance is defined!'); 
     else 
      alert('Instance is undefined!'); 
    } 
} 
// Finally 
var daGame = new Game(); 

或網格遊戲之前:

class Grid 
{ 
    public SeeIfStaticWorks() 
    { 
     console.log(Game.Game); 
     if (Game.Game) 
      alert('Instance is defined!'); 
     else 
      alert('Instance is undefined!'); 
    } 
} 
class Game 
{ 
    public Grid: Grid; 
    public static Game; 

    constructor() 
    { 
     Game.Game = this; 
     this.Grid = new Grid(); 
     this.Grid.SeeIfStaticWorks(); 
    } 
} 
// Finally 
var daGame = new Game(); 

Try it online.

+1

對不起,我不想聽起來粗魯,但這不是使用RequireJS並在不同的文件中使用遊戲和網格模塊。我目前的理解是,這個問題與[RequireJS中的循環引用](http://requirejs.org/docs/api.html#circular)有關,但是由於required需要的是TypeSCript中的關鍵字,因此無法應用該解決方案。 –

1

如果它可以幫助任何人,我已經成功通過創建道場框架內使用AMD的靜態變量包裝它的'聲明'函數(dojo的本地函數用於創建'類')。

(function() { 
'use strict'; 

define([ 
    'dojo/dom', 
    'dojo/_base/lang', 
    'dojo/_base/declare' 
], function (dom, lang, declare) { 


    var constants = { 
     SOME_CONSTANT: 'Here is it!' 
    }; 

    var Car = declare(null, { 
     constructor: function() { 

     }, 

     throttle: function() { 
      console.log('Vrrr!'); 
     } 
    }); 

    lang.mixin(Car, constants); 
    return Car; 

}); 

}());

在客戶端:

(function() { 
'use strict'; 
define([ 
    'model/Car', 
    'dojo/domReady!' 
], function (Car) { 
    var c = new Car(); 
    c.throttle(); 
    console.log(Car.SOME_CONSTANT); 
}); 

}());