Was bedeuten Angular 2-Hashtags in der Vorlage?

135

Ich arbeite mit Angular 2 und habe so etwas gefunden

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

und es funktioniert.

Ich verstehe jedoch nicht die Bedeutung von #searchBox . Ich habe auch im Dokument nichts Klares gefunden.

Kann mir jemand erklären, wie es funktioniert?

ackuser
quelle
2
Mögliches Duplikat von Was ist der Unterschied zwischen Klammern, Klammern und Sternchen in Angular2? - " Auf einem DOM-Element <div #mydiv> ein Verweis auf das Element ". Mit anderen Worten, wenn Sie #searchBoxdas Element haben, können Sie es searchBox.valueim Keyup-Handler verwenden.
Joe Clay
Es ist eine Variable.
Harry

Antworten:

177

Diese Syntax wird im Angular 2-Template-System verwendet, das DOM-Elemente als Variablen deklariert.

Hier gebe ich meiner Komponente eine Vorlagen-URL:

import {Component} from 'angular2/core';

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

export class HarrysApp {}

Vorlagen rendern HTML. In einer Vorlage können Sie Daten, Eigenschaftsbindung und Ereignisbindung verwenden. Dies wird mit der folgenden Syntax erreicht:

# - variable Aussage

() - Ereignisbindung

[] - Eigentumsbindung

[()] - Zwei-Wege-Eigenschaftsbindung

{{ }} - Interpolation

* - Strukturrichtlinien

Die #Syntax kann lokale Variablennamen deklarieren, die auf DOM-Objekte in einer Vorlage verweisen. z.B

 <span [hidden]="harry.value">*</span>
 <input type="text" #harry>
 {{ harry.value }}
Harry
quelle
6
Arbeitsbeispiel : <input #bla style="display: none;" value="Foo" /<div> {{bla.value}} </div>. Foo wird in div angezeigt.
Breitband
3
Und gibt es keine Möglichkeit, dass diese Variablendeklaration selbst eine Variable ist? Ich versuche, Materialmenüelemente aus einem komplexen verschachtelten Objekt von Menüs zu erstellen, und dies hat mich behindert. Ich kann die dom-Variablen scheinbar nicht dynamisch erstellen. Müssen sie im Dom wirklich fest codiert sein?
Crowmagnumb
2
Offizielle Dokumentreferenz: angle.io/guide/…
千 木 郷
31

Von angulartraining.com :

Vorlagenreferenzvariablen sind ein kleines Juwel, mit dem Sie viele schöne Dinge mit Angular erledigen können. Normalerweise nenne ich diese Funktion "Hashtag-Syntax", da sie sich auf ein einfaches Hashtag stützt, um einen Verweis auf ein Element in einer Vorlage zu erstellen:

<input #phone placeholder="phone number">

Die obige Syntax ist recht einfach: Sie erstellt einen Verweis auf das  Eingabeelement , der später in meiner Vorlage verwendet werden kann. Beachten Sie, dass der Bereich für diese Variable die gesamte HTML-Vorlage ist, in der die Referenz definiert ist.

So könnte ich diese Referenz verwenden, um den Wert der Eingabe zu erhalten, zum Beispiel:

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

Beachten Sie, dass das  Telefon für die Eingabe  auf die HTMLElement- Objektinstanz  verweist  . Infolgedessen verfügt das  Telefon  über alle Eigenschaften und Methoden eines HTMLElement (ID, Name, innerHTML, Wert usw.).

Dies ist eine gute Möglichkeit, um die Verwendung von ngModel oder einer anderen Art der Datenbindung in einer einfachen Form zu vermeiden, die hinsichtlich der Validierung nicht viel erfordert.


Funktioniert das auch mit Komponenten?

Die Antwort ist ja!

... das Beste daran ist, dass wir einen Verweis auf die eigentliche Komponenteninstanz HelloWorldComponent erhalten, damit wir auf alle Methoden oder Eigenschaften dieser Komponente zugreifen können (auch wenn sie als privat oder geschützt deklariert sind, was überraschend ist). ::

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

export class HelloComponent {
   name = 'Angular';
}

[...]

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

<!-- The following expression displays "Angular" -->
{{helloComp.name}}
Ruffin
quelle
2
"Auch wenn sie als privat oder geschützt deklariert sind, was überraschend ist" - denken Sie daran, dass Zugriffsspezifizierer ein Schutz für die Kompilierungszeit sind und normalerweise nichts tun, nachdem der Code kompiliert und ausgeführt wurde.
Tongfa
21

Es wird eine Vorlagenvariable erstellt, auf die verwiesen wird

  • das inputElement, wenn das Element ein einfaches DOM-Element ist
  • die Komponenten- oder Direktiveninstanz, wenn es sich um ein Element mit einer Komponente oder Direktive handelt
  • eine bestimmte Komponente oder Direktive, wenn sie wie #foo="bar"wann verwendet barwird
@Directive({ // or @Component
  ...
  exportAs: 'bar'
})

Eine solche Vorlagenvariable kann in Vorlagenbindungen oder in Elementabfragen wie referenziert werden

@ViewChild('searchBox') searchBox:HTMLInputElement;
Günter Zöchbauer
quelle
Das ist großartig. Übrigens - es ist dem ngModel ziemlich ähnlich, nicht wahr?
freundlicher Benutzer
Nicht wirklich. ngModelist für die Formularintegration. Sie können alle anderen Arten von Bindungen ohne ausführen ngModel.
Günter Zöchbauer
Letzte Sache, wie haben Sie verwendet, ngAfterViewInitohne es tatsächlich zu importieren? Und umsetzen? Es ist eine eingebaute Funktion auf Plunker?
freundlicher Benutzer
Nein, Angular hängt nicht davon ab, welche Lebenszyklusschnittstellen explizit deklariert werden. Wenn die Methode existiert, wird sie aufgerufen. Die explizite Implementierung der Schnittstellen ist jedoch eine gute Praxis.
Günter Zöchbauer