2016-06-19 47 views
5

C'è un modo per iniettare una dipendenza in una fabbrica di arredatori, usando il DI di Angular? Prendiamo il seguente codice come un esempio semplificato:Angolare 2 - Iniettare una dipendenza in una fabbrica di arredatori

@Component({ 
    selector: 'hello-component', 
    template: '<div>Hello World</div>' 
}) 
export class HelloComponent { 
    @PersonName() 
    name: string; 

    ngAfterViewInit() { 
    console.log(`Hello, ${this.name}`); 
    } 
} 

Qui, il comportamento previsto del PersonName decoratrice è per esso per accedere una dipendenza Person, e utilizzarlo per impostare la proprietà name della classe.

È possibile implementare il decoratore PersonName per il codice sopra riportato?

+0

Si desidera impostare il valore per 'nome' all'interno di' @PersonName() 'decoratore? – codef0rmer

+0

Sì, è vero. – Merott

risposta

4

È un po 'complicato farlo, perché i decoratori vengono eseguiti in fase di compilazione, non in fase di esecuzione. Quando viene eseguito il decoratore, non ci sono istanze della classe.

Già nel ng2.beta.10, ho usato questo per ottenere i dati dal servizio (non credo che si può dal componente, ma potrei sbagliarmi ...):

// some-route.ts 
@CanActivate((next, prev) => { 
    let store: any = getSingleton(Store); 
}) 

// injector.ts 
import {Injector} from 'angular2/core' 

let appInjectorRef: Injector; 

export const appInjector = (injector?: Injector) => { 
    if (injector) 
    appInjectorRef = injector; 
    return appInjectorRef; 
} 

export function getSingleton(token: any) { 
    let injector: Injector = appInjector(); 
    return injector.get(token); 
} 

.. per essere onesti, guardando questo codice ora non ho ide come funziona (; ma so che lo ha fatto allora. Non so quale sia lo stato adesso, o se ci sono stati cambiamenti della beta.10 relativi all'iniettore e ApplicationRef ...

+0

Qualche credito a https://github.com/angular/angular/issues/4112#issuecomment-153811572 con l'esempio di Plunker. –

+0

In ~ 2.0.0 appInjector() restituisce undefined. – lexigren

-2

È possibile effettuare quanto segue:

export class AnnotationExample { 
    @PersonName 
    name: string; 

    constructor() { 
    alert(this.name); 
    } 
} 

function PersonName(/*target: Function, fnName: string, fn: any*/) { 
    return {value: 'amit'}; 
} 

var whatIs = new AnnotationExample(); 
6

Attualmente, per iniettare le dipendenze nelle mie decoratori (e altre classi di moduli extra) sto usando questa soluzione:

import {Injectable, Injector} from "@angular/core"; 
@Injectable() 
export class ExtraModuleInjector { 
    private static injector; 

    public static get(token: any) { 
    if (ExtraModuleInjector.injector) { 
     return ExtraModuleInjector.injector.get(token); 
    } 
    } 

    constructor(public injector: Injector) { 
    ExtraModuleInjector.injector = injector; 
    } 
} 

Dopo essere stata iniettata al componente principale, permette di utilizzare il metodo get statico per ottenere le dipendenze durante l'esecuzione delle funzioni di runtime. Ancora in cerca di una soluzione migliore.

+0

Penso che ti sia dimenticato di aggiungere il codice dalla tua definizione del modulo, vero? Qualcosa come aggiungere '.then()' alla fine per impostare i valori di dipendenza? –