web-dev-qa-db-fra.com

Angular2 - Les variables privées doivent-elles être accessibles dans le modèle?

Si une variable est déclarée private sur une classe de composant, devrais-je pouvoir y accéder dans le modèle de ce composant?

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>{{title}}</h2>
      <h2>Hello {{userName}}</h2> // I am getting this name
    </div>
  `,
})
export class App {
  public title = 'Angular 2';
  private userName = "Test Name"; //declared as private
}
118
3gwebtrain

Non, vous ne devriez pas utiliser de variables privées dans vos modèles.

Bien que j'aime bien le réponse de drewmoore et que j'y vois une logique conceptuelle parfaite, sa mise en œuvre est fausse. Les modèles n'existent pas dans les classes de composants, mais en dehors d'elles. Jetez un oeil à ce repo pour la preuve.

Cela fonctionne uniquement parce que le mot clé private de TypeScript ne rend pas le membre privé. La compilation Just-in-Time se produit dans un navigateur au moment de l'exécution et JS n'a pas encore de concept de membre privé (encore?). Le mérite revient à Sander Elias pour m'avoir mis sur la bonne voie.

Avec la compilation ngc et Ahead-of-Time, vous obtiendrez des erreurs si vous essayez d'accéder aux membres privés du composant à partir d'un modèle. Clonez le référentiel de démonstration, changez la visibilité des membres de MyComponent en privé et vous obtiendrez des erreurs de compilation lors de l'exécution de ngc. Voici également réponse spécifique à la compilation Ahead-of-Time.

187
Yaroslav Admin

Edit: Cette réponse est maintenant incorrecte. Il n'y avait aucune indication officielle sur le sujet lorsque je l'ai posté, mais comme expliqué dans la réponse (excellente et correcte) de @ Yaroslov, ce n'est plus le cas: Codelizer maintenant met en garde et la compilation AoT échouera sur les références aux variables privées dans les modèles de composants. Cela dit, sur le plan conceptuel, tout reste valable, je vais donc laisser cette réponse, car elle semble avoir été utile.


Oui, c'est prévu.

Gardez à l'esprit que private et les autres modificateurs d'accès sont des constructions TypeScript, alors que Component/controller/template sont des constructions angular dont TypeScript ne connaît rien. Les modificateurs d'accès contrôlent la visibilité entre classes: Créer un champ private empêche d'autres classes pour y avoir accès, mais les modèles et les contrôleurs sont des éléments existants au sein de classes.

Ce n’est pas techniquement vrai, mais (au lieu de comprendre comment les classes se rapportent aux décorateurs et à leurs métadonnées), il peut être utile de penser de cette façon, car l’important (IMHO) est de ne plus considérer le modèle et le contrôleur comme distincts. en les considérant comme des parties unifiées de la structure Component - c’est l’un des aspects majeurs du modèle mental ng2.

En pensant de cette façon, nous nous attendons évidemment à ce que les variables private d'une classe de composant soient visibles dans son modèle. Pour la même raison, nous nous attendons à ce qu'elles soient visibles dans les méthodes private de cette classe.

81
awqueous

Bien que l'exemple de code indique que la question concerne TypeScript, elle n'a pas de balise TypeScript . Angular2 est également disponible pour Dart, ce qui constitue une différence notable par rapport à Dart.

Dans Dart le modèle ne peut pas faire référence à des variables privées de la classe de composants , car Dart, contrairement à TypeScript, empêche efficacement l’accès des membres privés de l’extérieur.

Je soutiens toujours la suggestion de @drewmoores de penser au composant et à son modèle en une seule unité.

Update (TS) Il semble qu'avec la compilation hors ligne, l'accès aux propriétés privées deviendra plus limité également dans Angular2 TS https: // github. com/angular/angular/issues/11422

14
Günter Zöchbauer

Les variables privées peuvent être utilisées dans le modèle de composant. Voir la feuille de triche angular2 pour le guide: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

Une explication plus détaillée sur les membres publics/privés des classes dans TypeScript peut être trouvée ici: https://www.typescriptlang.org/docs/handbook/classes.html .

Tous les membres sont par défaut publics. Les membres publics sont accessibles de l'extérieur de la classe de composant avec l'instance de la classe. Mais les membres privés ne sont accessibles que dans les fonctions de membre de classe.

3
anusreemn

Une solution de contournement pourrait consister à utiliser des variables privées dans un fichier ts et à utiliser des accesseurs.

private _userName = "Test Name";
get userName() {
  return this._userName;
}

C'est une bonne approche car le fichier ts et le code HTML restent indépendants. Même si vous modifiez le nom de la variable _userName dans le fichier ts, vous ne devez effectuer aucune modification dans le fichier de modèle.

1
Franklin Pious

La réponse courte est non, vous ne devriez pas pouvoir accéder aux membres privés à partir du modèle car il est techniquement séparé du fichier TS.

0
Ivens Applyrs