Come ottenere il riferimento del componente associato a ElementRef in Angular 2

Ho questo componente nel mio modello:

  

L’ vector-editor ha la seguente struttura:

 export class VerticeControlComponent implements OnInit { @Input() x: number; @Input() y: number; @Input() z: number; ... } 

Nella mia applicazione ho preso un riferimento al #scaleControl usando

 @ViewChild('scaleControl') scaleControl: ElementRef; 

Ora se scaleControl sulla console ottengo questo risultato:

inserisci la descrizione dell'immagine qui

Come si può vedere, il riferimento non è nullo e tutte le proprietà del mio componente ci sono. Voglio accedere a queste proprietà, ma nel codice il tipo effettivo di scaleControl è ElementRef e non VectorEditorControl come visto nell’output. Per questo motivo, TypeScript non consente di utilizzare this.scaleControl.x .

Ho anche provato a lanciare ElementRef questo modo

 var temp = this.scaleControl 

ma ricevo un errore che mi dice che non posso lanciare ElementRef in VectorEditorControl

Alla fine, ho provato ad accedere a this.scaleControl.nativeElement ma non è definito …

Cosa mi manca qui?

Dovresti sapere quanto segue sull’uso del decoratore di proprietà @ViewChild .

Utilizza le seguenti proprietà dei metadati:

  • selettore : il tipo di direttiva o il nome utilizzato per l’interrogazione.
  • read – legge un diverso token dagli elementi interrogati.

Dal codice sorgente:

 export interface ViewChildDecorator { /** * You can use ViewChild to get the first element or the directive matching * the selector from the * view DOM. If the view DOM changes, and a new child matches the selector, * the property will be updated. * * View queries are set before the `ngAfterViewInit` callback is called. * * **Metadata Properties**: * * * **selector** - the directive type or the name used for querying. * * **read** - read a different token from the queried elements. */ (selector: Type|Function|string, {read}?: {read?: any}): any; new (selector: Type|Function|string, {read}?: {read?: any}): ViewChild; } 

Se non si fornisce il parametro di read , @ViewChild() restituirà:

  • istanza del componente, se presente.
  • ElementRef se non è applicato alcun componente
  • token diverso dagli elementi interrogati se si imposta la proprietà di lettura

Quindi se vuoi ottenere ElementRef dal figlio che è angular2 component ( VerticeControlComponent ) devi dire esplicitamente usando read: ElementRef :

 @ViewChild('scaleControl', {read: ElementRef}) scaleControl: ElementRef; 

E poi dentro l’hook ngAfterViewInit o dopo puoi scrivere this.scaleControl.nativeElement per ottenere l’elemento DOM.

Aggiornare

Ho scritto presto:

  • token diverso dagli elementi interrogati se si imposta la proprietà di lettura

Ora voglio aggiungere quello che possiamo leggere esattamente:

  • ElementRef

  • TemplateRef

  • ViewContainerRef

  • Provider

Cosa significa Provider qui?

Significa che se abbiamo definito qualsiasi provider (in componente o direttiva) su un elemento specifico, possiamo leggerlo.

 @Component({ selector: 'child', template: ` 

I'm child

`, providers: [ { provide: 'test', useValue: 'x' } ] }) export class ChildComponent { }

Quindi nel consumatore di questo componente possiamo scrivere

 @ViewChild(ChildComponent, { read: 'test' }) providerToken: string; 

per ottenere il valore x .

Esempio

Guarda anche:

  • Quali sono tutti i selettori validi per ViewChild e ContentChild?

Ho ricevuto questo errore due volte. Una volta nel mio codice principale e una seconda volta nel codice di prova (specifica).

Entrambe le volte mancava qualche riferimento. Il compilatore angular (transpiler) non mostra alcun errore durante la compilazione, ma in seguito, silenziosamente, non fornisce alcun riferimento al file

  1. La prima volta che ho ricevuto questo errore nel codice principale abc.component.ts. Ricordo che questa volta abbiamo incluso correttamente i riferimenti necessari per questo bambino in questo abc.component.ts. Questo componente figlio proveniva da un altro modulo. L’errore è stato risolto solo dopo che questo componente figlio non è stato incluso nel file module.ts

    dichiarazioni: [VectorEditorComponent, ….],

  2. La seconda volta abbiamo affrontato questo problema nel file spec. Stavo cercando di verificare alcune aspettative sulla necessità di impostare una proprietà del componente figlio. Non stavo ottenendo l’istanza del componente figlio ma ottenendo ElementRef. Anche qui, non c’era nessun errore di compilazione. Il problema era leggermente diverso qui. Avevo usato No_Errors_Schema. Quindi, sebbene non avessimo incluso il componente nel file spec, angular non si lamentava, ma imposta ElementRef invece del componente figlio. L’errore è scomparso quando abbiamo importato il modulo e l’abbiamo fornito nella configurazione del test del file spec.

Nel secondo caso posso capire che non era dovuto a uno schema di errore. Ma nel primo caso, penso che il team Angular debba migliorare. Non vi è alcun indizio sul motivo per cui il componente non è stato fornito ma viene fornito ElementRef.

Al momento della stesura, ti consiglio di utilizzare il seguente metodo:

 @ViewChild('scaleControl') scaleControl: ElementRef; 

È quindi ansible avere accesso a entrambi i tipi.

  • ElementRef: using scaleControl
  • VerticeControlComponent: using scaleControl.nativeElement