Que signifient les hashtags Angular 2 dans le modèle?

135

Je travaille avec angular 2 et j'ai trouvé quelque chose comme

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

et il fonctionne.

Cependant, je ne comprends pas la signification de #searchBox . Je n'ai rien trouvé de clair non plus dans la doc.

Quelqu'un pourrait-il m'expliquer comment cela fonctionne?

ackuser
la source
2
Copie possible de Quelle est la différence entre les parenthèses, les crochets et les astérisques dans Angular2? - " Sur un élément DOM <div #mydiv> une référence à l'élément ". En d'autres termes, avoir #searchBoxsur l'élément est ce qui vous permet d'utiliser searchBox.valuedans le gestionnaire de keyup.
Joe Clay
c'est une variable.
Harry

Réponses:

177

C'est la syntaxe utilisée dans le système de modèles Angular 2 qui déclare les éléments DOM comme des variables.

Ici, je donne à mon composant une URL de modèle:

import {Component} from 'angular2/core';

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

export class HarrysApp {}

Les modèles rendent le HTML. Dans un modèle, vous pouvez utiliser des données, une liaison de propriété et une liaison d'événement. Ceci est accompli avec la syntaxe suivante:

# - déclaration de variable

() - liaison d'événement

[] - liaison de propriété

[()] - liaison de propriété bidirectionnelle

{{ }} - interpolation

* - directives structurelles

La #syntaxe peut déclarer des noms de variables locales qui font référence aux objets DOM dans un modèle. par exemple

 <span [hidden]="harry.value">*</span>
 <input type="text" #harry>
 {{ harry.value }}
Harry
la source
6
Exemple de travail: <input #bla style="display: none;" value="Foo" /<div> {{bla.value}} </div>. Foo est affiché en div.
haut débit
3
Et il n'y a aucun moyen pour cette déclaration de variable elle-même d'être une variable? J'essaie de créer des éléments de menu matériels à partir d'un objet complexe de menus imbriqués et cela m'a bloqué. Je n'arrive pas à créer dynamiquement les variables dom. Ont-ils vraiment besoin d'être codés en dur dans le dom?
crowmagnumb
2
Référence du Document Officiel: angular.io/guide/…
千 木 郷
65

Lorsque vous définissez cette #searchBox, vous pouvez obtenir cette entrée sur votre TypeScript comme

    @ViewChild('searchBox') searchBox;
    console.info(searchBox.nativeElement.value)

ÉDITER

Ajout d'un exemple: https://plnkr.co/edit/w2FVfKlWP72pzXIsfsCU?p=preview

Matheus Martins
la source
31

De angulartraining.com :

Les variables de référence de modèle sont un petit bijou qui permet de faire beaucoup de belles choses avec Angular. J'appelle généralement cette fonctionnalité «la syntaxe du hashtag» car, eh bien, elle repose sur un simple hashtag pour créer une référence à un élément dans un modèle:

<input #phone placeholder="phone number">

Ce que fait la syntaxe ci-dessus est assez simple: elle crée une référence à l'  élément d' entrée qui peut être utilisée plus tard dans mon modèle. Notez que la portée de cette variable est l'ensemble du modèle HTML dans lequel la référence est définie.

Voici comment je pourrais utiliser cette référence pour obtenir la valeur de l'entrée, par exemple:

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

Notez que  phone  fait référence à l'  instance d' objet HTMLElement pour l'  entrée . En conséquence, le  téléphone  possède toutes les propriétés et méthodes de tout HTMLElement (id, nom, innerHTML, valeur, etc.)

Ce qui précède est un bon moyen d'éviter d'utiliser ngModel ou un autre type de liaison de données sous une forme simple qui ne nécessite pas beaucoup en termes de validation.


Cela fonctionne-t-il également avec les composants?

La réponse est oui!

... la meilleure partie de cela est que nous obtenons une référence à l'instance de composant réelle, HelloWorldComponent, afin que nous puissions accéder à toutes les méthodes ou propriétés de ce composant (même si elles sont déclarées comme privées ou protégées, ce qui est surprenant) :

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

export class HelloComponent {
   name = 'Angular';
}

[...]

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

<!-- The following expression displays "Angular" -->
{{helloComp.name}}
ruffin
la source
2
"même s'ils sont déclarés comme privés ou protégés, ce qui est surprenant" - gardez à l'esprit que les spécificateurs d'accès sont un garde-temps à la compilation et ne font généralement rien après la compilation et l'exécution du code.
Tongfa
21

Il crée une variable de modèle qui référence

  • l' inputélément si l'élément est un élément DOM simple
  • l'instance de composant ou de directive s'il s'agit d'un élément avec un composant ou une directive
  • un composant ou une directive spécifique s'il est utilisé comme #foo="bar"quand barest
@Directive({ // or @Component
  ...
  exportAs: 'bar'
})

Une telle variable de modèle peut être référencée dans des liaisons de modèle ou dans des requêtes d'élément comme

@ViewChild('searchBox') searchBox:HTMLInputElement;
Günter Zöchbauer
la source
Ceci est incroyable. Au fait, c'est assez similaire au ngModel, n'est-ce pas?
utilisateur aimable
Pas vraiment. ngModelest pour l'intégration des formulaires. Vous pouvez effectuer tous les autres types de liaisons sans ngModel.
Günter Zöchbauer
Dernière chose, comment l'avez-vous utilisé ngAfterViewInitsans l'importer? Et la mise en œuvre? C'est une fonctionnalité intégrée sur plunker?
utilisateur aimable
Non, Angular ne dépend pas de la déclaration explicite des interfaces du cycle de vie. Si la méthode existe, elle est appelée. L'implémentation explicite des interfaces est cependant une bonne pratique.
Günter Zöchbauer