2015-12-21 15 views
10

Sto creando un progetto in cui ho bisogno di una classe "costanti" per contenere alcuni valori di configurazione. Ecco un estratto di questa classe:Iniezione rispetto alla classe statica globale con Angular 2

export class Constants 
{ 
    static Configuration = class 
    { 
     static CookieName:string = 'etl_language'; 
    }; 

    ... 

    static View = class 
    { 
     static Militaries:string = 'militaries'; 
     static Mutants:string = 'mutants'; 
     static Objects:string = 'objects'; 
     static Scientists:string = 'scientists'; 
    }; 
} 

Quando sono in un componente con angolare 2, posso usare quella classe importandolo:

import {Constants} from "../../misc/constants"; 

E poi, basta fare riferimento a esso:

this.cookieName = Constants.Configuration.CookieName; 

funziona abbastanza bene, ma ho la sensazione che avrei dovuto utilizzare il motore di iniezione di dipendenza di angolare 2 per iniettare un riferimento a quella classe nel costruttore, ma sembra un po 'eccessivo. Tuttavia, ho la sensazione di violare il "modo angolare" di fare le cose, quindi non so se posso restare con la mia soluzione o se devo usare DI.

Qualche consiglio?

+1

Con DI è possibile eliminare tutte le risorse 'static' e iniettare la stessa istanza di oggetto (un singleton) ovunque. –

risposta

6

Cosa potrei suggerisco di fare è invece cambiare le Constants classi di aver proprietà di sola lettura e creare una Providers[] da loro in questo modo

@Injectable() 
public class ConfigurationConstants() { 
    private _cookieName:string = 'etl_language'; 
    ... 
    get cookieName():string { 
    return this._cookieName; 
    } 
    ... 
} 

export var CONSTANTS_PROVIDERS:Provider[] = [ 
    provide(ConfigurationConstants, {useClass: ConfigurationConstants}), 
    provide(ViewConstants, {useClass: ViewConstatns}) 
]; 

Quindi è possibile avviare questi fornitori nell'iniettore di livello superiore per la propria applicazione rendendoli disponibili ovunque possano essere necessari.

import {CONSTANTS_PROVIDERS} from './constants'; 

bootstrap(App, [CONSTANTS_PROVIDERS]) 
    .catch(err => console.error(err)); 

Ecco un Plunk per dimostrare: http://plnkr.co/edit/RPjDxoIZ8wLY3DDIdhJF

Edit 2: Plunker è indietro e ho aggiornato l'esempio

Edit: Plunkr è morto in questo momento così posso aggiornarlo ma nel mio commento intendevo qualcosa del genere (non l'ho provato ma dovrebbe funzionare):

public class SubConstants() { 
    private _someString:string = 'Some String'; 
    ... 
    get someString():string { 
    return this._someString; 
    } 
    ... 
} 

@Injectable() 
public class ConfigurationConstants() { 
    private _cookieName:string = 'etl_language'; 
    private _subConstants:SubConstants = new SubConstants(); 
    ... 
    get cookieName():string { 
    return this._cookieName; 
    } 

    get subConstants():SubConstants { 
    return this._subConstants; 
    } 
    ... 
} 

// ... this would allow you to then do: 
confConstants.subConstants.someString 
// assuming you injected ConfigurationConstants as confConstants 

Ancora una volta questo è più codice del tuo suggerimento delle classi interne, quindi probabilmente è fino a che tu preferisci.

+0

Oltre alla classe "Constants", ho anche una classe "Language" che dovrebbe seguire lo stesso schema. Il problema è che la classe contiene un sacco di classe interiore. A volte, puoi avere una chiave come "Language.Materials.Metal.Name". Il tuo approccio è interessante ma la struttura della classe mi farebbe scrivere ** un sacco ** di codice. Non sarebbe interessante mescolare il tuo approccio con il mio? Rimuovo tutte le "statiche" della mia classe ma la esporto come una classe come hai fatto tu? – ssougnez

+0

Intendevo "rimuovo tutte le statiche dalla mia classe ma io ** le ho iniettate ** come classe come hai fatto tu?" – ssougnez

+0

Personalmente eviterei la classe nidificata e userei la composizione per ottenere le chiavi annidate che stai cercando. Aggiornerò la mia risposta con un esempio – Zyzle

3

DI è facoltativo, ma è utile per i casi in cui si desidera lavorare con un'istanza di un oggetto. Le importazioni sono ok in molti casi, ma DI separa il codice dall'istanza dell'istanza. Ciò è utile se stai eseguendo test automatici o vuoi che il tuo componente sia flessibile e accetti qualsiasi oggetto con una data firma.

Ho qualche informazione in più su Di qui, se siete interessati: http://www.syntaxsuccess.com/viewarticle/dependency-injection-in-angular-2.0

+0

Sì, questo è il motivo per cui sto cercando un modo migliore per ottenere questo rispetto a quello che sto attualmente utilizzando. La risposta di Zyzle sembra essere un buon inizio. Grazie – ssougnez

0

Il mio consiglio, per quello che vale. Non utilizzare mai l'iniezione di dipendenza a meno che non sia effettivamente necessario per risolvere un problema.

L'uso di DI dove non è necessario, o peggio, l'uso sistemico di DI in un'intera applicazione solo per soddisfare alcune strutture eccessivamente impegnative porterà a un codice incomprensibile. (Probabilmente vero per qualsiasi modello di design).

Il DI gerarchico di Angular sembra particolarmente eclatante per me. Una volta che la tua applicazione diventerà abbastanza grande, risolvendo ciò che sta risolvendo una particolare dipendenza e con quale altra istanza viene condivisa, sarà un enigma che permea l'intera base di codice.

Problemi correlati