¿Qué significan los hashtags de Angular 2 en la plantilla?

135

Estoy trabajando con angular 2 y he encontrado algo como

<input #searchBox (keyup)="search(searchBox.value)"

y funciona.

Sin embargo, no entiendo el significado de #searchBox . No he encontrado nada claro tampoco en el documento.

¿Alguien podría explicarme cómo funciona?

ackuser
fuente
2
Posible duplicado de ¿Cuál es la diferencia entre paréntesis, corchetes y asteriscos en Angular2? - " En un elemento DOM <div #mydiv> una referencia al elemento ". En otras palabras, tener #searchBoxen el elemento es lo que le permite usar searchBox.valueen el controlador de keyup.
Joe Clay
Es una variable.
Harry

Respuestas:

177

Es la sintaxis utilizada en el sistema de plantillas Angular 2 que declara elementos DOM como variables.

Aquí le doy a mi componente una URL de plantilla:

import {Component} from 'angular2/core';

@Component({
   selector: 'harrys-app',
   templateUrl: 'components/harry/helloworld.component.html'
})

export class HarrysApp {}

Las plantillas representan HTML. En una plantilla puede usar datos, enlace de propiedades y enlace de eventos. Esto se logra con la siguiente sintaxis:

# - declaración variable

() - enlace de eventos

[] - enlace de propiedad

[()] - enlace de propiedad bidireccional

{{ }} - interpolación

* - directivas estructurales

La #sintaxis puede declarar nombres de variables locales que hacen referencia a objetos DOM en una plantilla. p.ej

 <span [hidden]="harry.value">*</span>
 <input type="text" #harry>
 {{ harry.value }}
Harry
fuente
66
Ejemplo de trabajo: <input #bla style="display: none;" value="Foo" /<div> {{bla.value}} </div>. Foo se muestra en div.
banda ancha
3
¿Y no hay forma de que esa declaración de variable en sí misma sea una variable? Estoy tratando de crear elementos de menú de material a partir de un objeto complejo de menús anidados y esto me ha bloqueado. Parece que no puedo crear dinámicamente las variables dom. ¿Realmente necesitan estar codificados en el dom?
crowmagnumb
2
Referencia oficial del documento: angular.io/guide/…
千 木 郷
31

Desde angulartraining.com :

Las variables de referencia de plantilla son una pequeña joya que permite hacer muchas cosas buenas con Angular. Normalmente llamo a esa característica "la sintaxis de hashtag" porque, bueno, se basa en un simple hashtag para crear una referencia a un elemento en una plantilla:

<input #phone placeholder="phone number">

Lo que hace la sintaxis anterior es bastante simple: crea una referencia al  elemento de entrada que se puede usar más adelante en mi plantilla. Tenga en cuenta que el alcance de esta variable es la plantilla HTML completa en la que se define la referencia.

Así es como podría usar esa referencia para obtener el valor de la entrada, por ejemplo:

<!-- phone refers to the input element --> 
<button (click)="callPhone(phone.value)">Call</button>

Tenga en cuenta que el  teléfono  hace referencia a la  instancia del objeto HTMLElement para la  entrada . Como resultado,  teléfono  tiene todas las propiedades y métodos de cualquier elemento HTMLE (id, nombre, innerHTML, valor, etc.)

Lo anterior es una buena manera de evitar el uso de ngModel u otro tipo de enlace de datos en una forma simple que no requiere mucho en términos de validación.


¿Esto también funciona con componentes?

¡La respuesta es sí!

... la mejor parte es que estamos obteniendo una referencia a la instancia del componente real, HelloWorldComponent, para que podamos acceder a cualquier método o propiedades de ese componente (incluso si se declaran como privados o protegidos, lo cual es sorprendente) :

@Component({
  selector: 'app-hello',
  // ...

export class HelloComponent {
   name = 'Angular';
}

[...]

<app-hello #helloComp></app-hello>

<!-- The following expression displays "Angular" -->
{{helloComp.name}}
ruffin
fuente
2
"incluso si se declaran como privados o protegidos, lo cual es sorprendente": tenga en cuenta que los especificadores de acceso son una protección de tiempo de compilación y, por lo general, no hacen nada después de compilar y ejecutar el código.
Tongfa
21

Crea una variable de plantilla que hace referencia

  • el inputelemento si el elemento es un elemento DOM simple
  • la instancia de componente o directiva si es un elemento con un componente o directiva
  • algún componente específico o directiva si se usa como #foo="bar"cuando bares
@Directive({ // or @Component
  ...
  exportAs: 'bar'
})

Dicha variable de plantilla se puede hacer referencia en enlaces de plantilla o en consultas de elementos como

@ViewChild('searchBox') searchBox:HTMLInputElement;
Günter Zöchbauer
fuente
Esto es increíble. Por cierto, es bastante similar al ngModel, ¿no?
amable usuario
Realmente no. ngModeles para la integración de formularios. Puede hacer todos los otros tipos de enlaces sin ngModel.
Günter Zöchbauer
Lo último, ¿cómo lo usaste ngAfterViewInitsin importarlo realmente? E implementando? ¿Es una función incorporada en Plunker?
usuario amable
No, Angular no depende de que las interfaces del ciclo de vida se declaren explícitamente. Si el método existe, se llama. Sin embargo, implementar las interfaces explícitamente es una buena práctica.
Günter Zöchbauer