2015-12-21 13 views
10

Tworzę projekt, w którym potrzebuję klasy "constants", aby zawierać pewne wartości konfiguracyjne. Oto fragment tej klasy:Injection versus globalna klasa statyczna z 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'; 
    }; 
} 

Kiedy jestem w składniku z Kątowymi 2, można używać tej klasy importując go:

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

, a potem po prostu odwołać go:

this.cookieName = Constants.Configuration.CookieName; 

działa całkiem dobrze, ale mam wrażenie, że powinienem użyć silnika wtrysku zależność kątowa 2 wstrzyknąć odniesienie do tej klasy w konstruktorze, ale wydaje się nieco overkill. Mam jednak wrażenie, że naruszam "Angularny sposób" robienia rzeczy, więc nie wiem, czy mogę trzymać się mojego rozwiązania, czy też muszę korzystać z DI.

Każda rada?

+1

Dzięki DI możesz pozbyć się wszystkich rzeczy 'statycznych' i wstrzyknąć wszędzie tę samą instancję obiektu (singleton). –

Odpowiedz

6

Co może sugerować robi zamiast się zmienić swoje zajęcia Constants się tylko do odczytu właściwości i stworzyć Providers[] od nich jak tak

@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}) 
]; 

Następnie można załadować tych dostawców do wtryskiwacza najwyższego poziomu dla aplikacji, dzięki czemu są one dostępne wszędzie tam, gdzie mogą być potrzebne.

import {CONSTANTS_PROVIDERS} from './constants'; 

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

Oto upadać wykazać: http://plnkr.co/edit/RPjDxoIZ8wLY3DDIdhJF

Edycja 2: Plunker powraca teraz i mam zaktualizowane przykładzie

Edit: Plunkr żyje teraz tak mogę aktualizacja, ale w moim komentarzu miałem na myśli coś takiego (nie testowałem tego, ale powinno działać):

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 

Znowu jest to kod bardziej niż sugestia klas wewnętrznych, więc prawdopodobnie zależy to od Ciebie.

+0

Oprócz klasy "Constants", mam również klasę "Language", która powinna mieć ten sam wzór. Problem polega na tym, że klasa zawiera dużo wewnętrznej klasy. Czasami możesz mieć klucz taki jak "Language.Materials.Metal.Name". Twoje podejście jest interesujące, ale struktura klasy sprawi, że napiszę ** dużo ** kodu. Czy nie byłoby interesujące połączenie twojego podejścia z moim? Usuwam wszystkie "statyczne" z mojej klasy, ale eksportuję ją jako klasę, tak jak ty? – ssougnez

+0

Miałem na myśli "Usunąłem wszystkie statyczne z mojej klasy, ale ja ** wstrzyknę ** to jako klasę tak jak ty?" – ssougnez

+0

Osobiście uniknęłbym zagnieżdżonej klasyfikacji i użycia kompozycji, aby uzyskać klucze zagnieżdżone, których szukasz. Zaktualizuję moją odpowiedź na przykładzie. – Zyzle

3

DI jest opcjonalne, ale jest dobre dla przypadków, w których chcesz pracować z instancją obiektu. W wielu przypadkach importowanie jest ok, ale DI oddziela kod od instancji instancji. Jest to korzystne, jeśli wykonujesz test automatyczny lub chcesz, aby Twój komponent był elastyczny i akceptował dowolny obiekt z danym podpisem.

mam trochę więcej informacji na temat DI tutaj, jeśli jesteś zainteresowany: http://www.syntaxsuccess.com/viewarticle/dependency-injection-in-angular-2.0

+0

Tak, dlatego szukam lepszego sposobu na osiągnięcie tego niż ten, którego obecnie używam. Odpowiedź Zyzle wydaje się być dobrym początkiem. Dzięki – ssougnez

0

Moja rada, jaka jest wartość. Nigdy nie używaj zastrzyku zależności, chyba że faktycznie potrzebujesz go do rozwiązania problemu.

Używanie Dl, gdy nie jest potrzebne lub, co gorsza, systemowe stosowanie DI w całej aplikacji tylko po to, by zaspokoić niektóre zbyt trudne ramy, spowoduje, że kod będzie niezrozumiały. (Prawdopodobnie jest to prawda w przypadku dowolnego wzorca projektowego).

Hierarchiczna DI Angulara wydaje mi się szczególnie szokująca. Gdy aplikacja stanie się wystarczająco duża, aby opracować rozwiązanie konkretnej zależności i to, z czym jeszcze jest udostępniana, będzie to zagadka, która przenika całą twoją bazę kodów.

Powiązane problemy