2013-08-24 5 views
0

En utilisant TypeScript 0.9.1.1, lorsque vous essayez d'accéder à une variable statique à partir d'un autre module/fichier, il est indéfini.TypeScript: utilisation de variables statiques avec RequireJS AMD

code Exemple:

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; 

Contrôle Game.Game avant d'appeler this.Grid.SeeIfStaticWorks(); montre qu'il est défini:

http://j.mp/1dCY8Ec

Mais en essayant d'y accéder à l'intérieur SeeIfStaticWorks() est indéfini:

http://j.mp/1dCYISe

La question est: Comment être capable d'accéder à des variables statiques d'autres modules?


Mise à jour:

Courir tout le code d'un fichier permet d'utiliser la variable statique entre les modules (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(); 

Si j'utilise la même logique avec AMD RequireJS la variable statique non définie lors de l'appel 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; 

Répondre

1

Ceci est parce que lorsque le fichier est Game.ts analysables Game.Game n'est pas défini. Vous pouvez voir que dans le javascript généré:

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

Pour avoir des variables statiques disponibles lorsque vous exportez quelque chose que vous devez les mettre au point de définition (non paresseusement comme dans votre cas).Alors:

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

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

Vous pouvez voir le javascript généré:

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; 
})(); 

Comment gérer les singletons est une discussion séparée. Mais je crois que le code ci-dessus est suffisant. (vous pouvez mettre des contrôles supplémentaires si vous voulez un vrai singleton).

+0

Cela ne fonctionnera pas non plus parce que 'SeeIfStaticWorks()' serait exécuté avant que Game.Game' ne soit instancié. J'ai posté une mise à jour à la question avec un code plus proche de ce que je pourrais utiliser. Le problème semble être lié à RequireJS. Nice AngularJs/TS vidéos btw :) –

+0

Puisqu'il ne fonctionne pas de cette façon, pourriez-vous s'il vous plaît supprimer la réponse? Cela aiderait à obtenir une réponse correcte plus rapidement. –

+0

voir mon autre réponse – basarat

0

Le code indépendant de l'ordre suivant fonctionne. Jeu Démo avant Grille:

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(); 

ou grille avant le match:

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

Désolé, je ne veux pas paraître grossier mais cela n'utilise pas RequireJS et ayant les modules Game et Grid dans des fichiers différents. Ma compréhension actuelle est que le problème a à voir avec [des références circulaires dans RequireJS] (http://requirejs.org/docs/api.html#circular) mais la solution ne peut pas être appliquée puisque requis est un mot-clé dans TypeSCript . –

1

Dans le cas où il peut aider quelqu'un, je l'ai réussi à créer des variables statiques à l'aide d'AMD dans le cadre du dojo par envelopper sa fonction 'declare' (la fonction native de dojo pour créer 'classes').

(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; 

}); 

}());

dans le client:

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

}());

Questions connexes