2016-04-05 60 views
6

Hai bisogno di aiuto per fornire un OpaqueToken. Utilizzo di Angular 2 beta-12. Funziona bene se la chiave del provider è una stringa, ma non funziona quando si utilizza OpaqueToken. Nella classe Bambino, SF non è definito.angular 2 OpaqueToken

Parent Classe: Classe

export let SF = new OpaqueToken('sf'); 

export class A { 
    testMsg: string = 'hello'; 
} 

@Component({ 
    template: `<child></child>`, 
    providers: [ 
    provide(SF, {useValue: A}), 
    provide('justString', {useValue: 'hi'}) 
    ] 
}) 
export class App {} 

bambini:

import {Component, Injector, Inject, OpaqueToken} from 'angular2/core' 
import {SF, A} from './app' 
console.log("******", SF); // undefined 
@Component({ 
    selector: 'child', 
    template: ` 
    $$CHILD Rendered$$ {{a}} 
    ` 
}) 
export class Child { 
    //constructor(@Inject(SF) private a: A) {} // doesn't work 
    constructor(@Inject('justString') private a: string) {} 
} 

eccezioni che ricevo:

angular2.min.js: 17EXCEPTION: Impossibile risolvere tutti i parametri per "Bambino" (@ Inject (undefined)). Assicurati che tutti i parametri siano decorati con Inject o abbiano annotazioni di tipo valide e che "Child" sia decorato con Injectable.

risposta

9

È perché si ha una dipendenza ciclica tra i moduli che contengono classi genitore e figlio.

Se si definisce il token opaco in un terzo modulo e lo si include negli altri, funzionerà.

Ad esempio un modulo costante:

export let SF = new OpaqueToken('sf'); 

E negli altri due moduli:

import { SF } from './constants'; 
+0

che funziona molto meglio !! grazie. http://plnkr.co/edit/7mVEoE – Elijah

1

Suppongo che le vostre classi padre e figlio sono in file diversi, e che si sta importando Child nel file principale in modo da poter mettere nel directives del Parent decoratore (che non hai fatto in il tuo esempio, ma altrimenti Child non verrà istanziato affatto, il che chiaramente non è il caso).

In tal caso è necessario utilizzare uno forwardRef su qualsiasi cosa definita nel file di classe padre utilizzato nel file di classe figlio, che deve essere caricato per primo perché è importato nella classe genitore, e quindi non è al corrente di nulla definito nel file successivamente caricato (senza la soluzione che è forwardRef)

Quindi,

import {forwardRef} from "angular2/core"; 
... 
constructor(@Inject(forwardRef(()=>SF)) private a: A) {} 

dovrebbe funzionare dove

constructor(@Inject(SF) private a: A) {} // doesn't work 

fallisce.

Sidenote: provide(SF, {useValue: A}), dove A è un riferimento a una classe piuttosto che a un'istanza, ha un odore di pesce. Non speculerò su cosa stai facendo, ma dirò che è molto più tipico vedere useValue utilizzato con un riferimento a un'istanza e useClass utilizzato con un riferimento a una classe.

+0

Grazie per l'aiuto, @drewmoore Che fa il lavoro. Strano che non sia mai menzionato in nessun esempio che ho visto. Infatti il ​​documento di riferimento angular.io parla di forwardRef che è necessario solo quando si dichiara una classe dopo il componente nello stesso file. Ora il sito di iniezione sembra un po 'ostile. Ugh. Usi OpaqueTokens in questo modo? Il mio caso d'uso ora consiste semplicemente nel posizionare oggetti globali nel contesto dei componenti. – Elijah