"Privat" und "öffentlich" in der Angular-Komponente

120

Wenn ich nicht hinzufügen , privat vor foo, loadBarund textich glaube , sie sind öffentlich standardmäßig.

export class RandomComponent {
  @Input() foo: string;
  @Output() loadBar = new EventEmitter();
  text: string;
}

Gibt es einen Anwendungsfall, wenn sie sich publicin der Komponente befinden?

Sollte ich aus Gründen der Kapselung / Sicherheit immer privatefür alle wie unten hinzufügen ?

export class RandomComponent {
  @Input() private foo: string;
  @Output() private loadBar = new EventEmitter();
  private text: string;
}

Vielen Dank

Hongbo Miao
quelle
Um einfach zu sein, kann eine private Funktion nur in der Komponente verwendet werden. Es ist nicht möglich, von einer anderen Komponente aus auf eine private Funktion zuzugreifen. Angenommen, eine Funktion, die im Dienst als privat deklariert wird, kann von keiner anderen Komponente aus aufgerufen werden.
Kevin

Antworten:

201

Als Antwort auf diese Frage gibt es viel zu sagen. Dies sind die ersten Gedanken, die mir in den Sinn kamen:

Denken Sie in erster Linie daran, dass dies privatenur ein Konstrukt zur Kompilierungszeit ist - es kann zur Laufzeit nicht erzwungen werden (siehe hier und hier für relevante Diskussionen). Bitte entbinden Sie sich daher von jeglichen Vorstellungen private, aus Sicherheitsgründen in irgendeiner Weise nützlich zu sein. Darum geht es einfach nicht.

Es ist etwa Verkapselung, und wenn Sie ein Feld oder eine Methode auf Ihrer Komponente haben , dass Sie darin einzukapseln wollen, so dass es klar , dass es nicht von anderswo zugegriffen werden soll, dann sollte man unbedingt machen private: Das ist , was privateist für: Es signalisiert Ihre Absicht, dass alles, was Sie angezogen haben, nicht von außerhalb der Klasse berührt werden sollte.

Das Gleiche gilt für public: Es handelt sich ebenfalls um ein Konstrukt nur zur Kompilierungszeit. Die Tatsache, dass Klassenmitglieder publicstandardmäßig true sind, hat zur Laufzeit genau null Bedeutung. Wenn Sie jedoch ein Mitglied haben, das Sie ausdrücklich als Teil der API Ihrer Klasse der Außenwelt aussetzen möchten, sollten Sie es unbedingt schaffen public, diese Absicht zu signalisieren: Dafür publicist es da.

Dies gilt alles für Typescript im Allgemeinen. Insbesondere in Angular gibt es definitiv gültige Anwendungsfälle für öffentliche Mitglieder in Komponentenklassen: Zum Beispiel bei der Implementierung des Container- / Komponentenmusters (auch bekannt als smart / dumm ), bei dem "dumme" Kinder "intelligente" Eltern über die Konstruktorinjektion injizieren, Es ist äußerst wichtig, dass Sie Ihre Absicht darüber mitteilen, welche Mitglieder der Eltern von den Kindern berührt werden sollen und welche nicht: Seien Sie ansonsten nicht überrascht, wenn Sie diese dummen Kinder im Schnapsschrank ihrer Eltern herumalbern sehen.

Also meine Antwort auf Ihre Frage:

sollte ich für alle wie unten immer privat hinzufügen?

ist ein nachdrückliches Nein . Sie sollten nicht immer hinzufügen, privateweil Sie damit den Zweck des Schlüsselworts zunichte machen, da es keine Absicht mehr signalisiert, wenn Sie es überall platzieren: Sie können es genauso gut nirgendwo platzieren.

zog mehr
quelle
5
Danke für die Erklärung. Aber vielleicht verstehe ich es falsch: Ich verstehe, dass die meisten Eigenschaften und Methoden privat sein müssen (= "nur für diese Komponente verwenden"). Die Antwort sollte also "JA standardmäßig" lauten, solange der Typ die Eigenschaft / Methode nicht nach außen aussetzen muss. Nein ? Warum schließen Sie Ihre Erklärung mit "Nein" ab (was wie ein "Nie" klingt)?
M'sieur Toph '21.
1
Ich habe zwei eckige Tutorials, und ich habe nicht herausgefunden, wann ich public verwenden soll. Es gibt viele Varianten für die Komponentenkommunikation: angle.io/docs/ts/latest/cookbook/… Wahrscheinlich sollten wir public nur für Eigenschaften und Methoden verwenden, die über Input Output definiert wurden. Aber ich bin mir nicht sicher.
Ruslan Borovok
Normalerweise muss ich 'public' verwenden, wenn ich eine Eigenschaft im Konstruktor deklariere, die nicht innerhalb der Klasse verwendet wird, sondern außerhalb (dh innerhalb einer Vorlage oder einer anderen Komponente).
Tuliomarchetto
18

@drewmoore bietet eine gute Antwort, da privat / öffentlich auf Absicht hinausläuft. Bei der Verwendung injizierter privater Werte sind jedoch noch einige weitere Punkte zu beachten:

Wenn wir TypeScript als Ausgabe des AoT-Kompilierungsprozesses ausgeben möchten, müssen wir sicherstellen, dass wir nur auf öffentliche Felder in den Vorlagen unserer Komponenten zugreifen **

Lucas
quelle
Zu Ihrem ersten Punkt: Diese Fehler haben nichts damit zu tun, dass ein Mitglied privat oder öffentlich ist. Sie zeigen lediglich an, dass eines nicht verwendet wird. Ihre zweiten beiden Punkte wären gültig, wenn es um das Verweisen auf private Mitglieder in Vorlagen ginge , aber nicht. Siehe hier für eine Frage, die
zog moore
@rewmoore, Sie sind richtig, und ich verstehe, dass sie anzeigen, dass sie nicht verwendet werden. Öffentliche Variablen können jedoch extern verwendet werden, sodass diese Warnung niemals ausgelöst wird. In Bezug auf die Fragen selbst "Gibt es einen Anwendungsfall, wenn sie in der Komponente öffentlich sind?", Weisen meine zweiten und dritten Punkte zumindest auf einen Anwendungsfall hin, wenn sie öffentlich sind , insbesondere wenn Sie sie in der Vorlage verwenden möchten (wie im zitierten Text angegeben).
Lucas