«Privé» et «public» dans le composant angulaire

120

Si je n'ajoute pas de privé avant foo, loadBaret text, je pense qu'ils sont publics par défaut.

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

Y a-t-il un cas d'utilisation lorsqu'ils sont publicdans le composant?

Pour des raisons d'encapsulation / sécurité, dois-je toujours ajouter privatepour chacun d'entre eux comme ci-dessous?

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

Merci

Hongbo Miao
la source
Pour être simple, une fonction privée ne peut être utilisée que dans le composant. Il n'est pas possible d'accéder à une fonction privée depuis un autre composant. Supposons qu'en service, si une fonction se déclare privée, elle ne peut pas être accessible depuis un autre composant.
Kevin

Réponses:

202

Il y a beaucoup à dire en réponse à cette question, ce sont les premières pensées qui me sont venues à l'esprit:

Tout d'abord, gardez à l'esprit qu'il privatene s'agit que d'une construction au moment de la compilation - elle ne peut pas être appliquée à l'exécution (voir ici et ici pour une discussion pertinente). En tant que tel, veuillez vous désabuser de toute notion d' privateêtre utile de quelque manière que ce soit à des fins de sécurité. Ce n'est tout simplement pas ce dont il s'agit.

Il s'agit d'encapsulation, et lorsque vous avez un champ ou une méthode sur votre composant que vous souhaitez encapsuler, en indiquant clairement qu'il ne doit pas être consulté de nulle part ailleurs, alors vous devez absolument le faire private: c'est à cela que privatesert: Cela signale votre intention de ne pas toucher à tout ce que vous avez mis en dehors de la classe.

Il en va de même pour public: il s'agit également d'une construction uniquement à la compilation, de sorte que le fait que les membres de la classe soient publicpar défaut, bien que true, n'a aucune signification au moment de l'exécution. Mais lorsque vous avez un membre que vous avez explicitement l'intention d'exposer au monde extérieur dans le cadre de l'API de votre classe, vous devez absolument le faire publicpour signaler cette intention: c'est à cela que publicsert.

Tout cela est applicable à Typescript en général. Dans Angular en particulier, il existe des cas d'utilisation définitivement valides pour avoir des membres publics sur des classes de composants: par exemple, lors de l'implémentation du modèle conteneur / composant (alias smart / dumb ), avec des enfants "stupides" injectant des parents "intelligents" via l'injection de constructeur, il est extrêmement important de communiquer votre intention sur ce que les membres du parent devraient et ne devraient pas être touchés par les enfants: Sinon, ne soyez pas surpris lorsque vous surprenez ces enfants stupides qui s'amusent dans l'armoire à alcool de leurs parents.

Alors, ma réponse à votre question:

dois-je toujours ajouter privé pour tous comme ci-dessous?

est un non catégorique . Vous ne devriez pas toujours ajouter privateparce que, ce faisant, vous allez à l'encontre de l'objectif du mot-clé, car il ne signale plus aucune intention si vous le mettez partout: vous pourriez aussi bien ne le mettre nulle part.

dessiné moore
la source
5
Merci pour l'explication. Mais peut-être que je me trompe: je comprends que la plupart du temps, les propriétés et les méthodes doivent être privées (= "pour ce composant uniquement"). La réponse devrait donc être "OUI par défaut, tant que le gars n'a pas besoin d'exposer la propriété / méthode à l'extérieur". Non ? Pourquoi conclure votre explication en répondant «non» (ce qui ressemble à un «jamais»)?
M'sieur Toph '21
1
J'ai rouge 2 tutoriels angulaires, et je n'ai pas compris quand je devrais utiliser public. Il existe de nombreuses variantes pour la communication des composants: angular.io/docs/ts/latest/cookbook/… Nous devrions probablement utiliser public uniquement pour les propriétés et les méthodes définies via Input Output. Mais je ne suis pas sur.
Ruslan Borovok
Je dois généralement utiliser «public» lorsque je déclare une propriété dans le constructeur qui n'est pas utilisée à l'intérieur de la classe, mais qui est utilisée à l'extérieur (c'est-à-dire à l'intérieur d'un modèle ou d'un autre composant).
tuliomarchetto
18

@drewmoore fournit une bonne réponse en ce sens que privé / public se résume à l'intention. Mais il y a quelques autres éléments à prendre en compte lors de l'utilisation de valeurs privées injectées:

Si nous voulons émettre TypeScript comme sortie du processus de compilation AoT, nous devons nous assurer que nous n'accédons qu'aux champs publics dans les modèles de nos composants **

Lucas
la source
Concernant votre premier point: ces erreurs n'ont rien à voir avec le fait qu'un membre soit privé ou public, elles indiquent simplement qu'un membre n'est pas utilisé. Vos deux seconds points seraient valides si la question portait sur le référencement de membres privés dans des modèles , mais ce n'est pas le cas. Voir ici pour une question qui est
drew moore
@drewmoore, vous avez raison, et je comprends qu'ils indiquent qu'ils ne sont pas utilisés. Cependant, les variables publiques peuvent être utilisées en externe afin de ne jamais déclencher cet avertissement. En ce qui concerne les questions elles-mêmes "Y a-t-il des cas d'utilisation lorsqu'ils sont publics dans le composant?", Je pense que mes deuxième et troisième points indiquent au moins un cas d'utilisation lorsqu'ils sont publics , en particulier lorsque vous souhaitez les utiliser dans le modèle (comme indiqué dans le texte cité).
Lucas