Angular2: ¿las variables privadas deben estar accesibles en la plantilla?

Si una variable se declara private en una clase de componente, ¿debería poder acceder a ella en la plantilla de ese componente?

 @Component({ selector: 'my-app', template: ` 

{{title}}

Hello {{userName}}

// I am getting this name
`, }) export class App { public title = 'Angular 2'; private userName = "Test Name"; //declared as private }

Editar: Esta respuesta ahora es incorrecta. No hubo orientación oficial sobre el tema cuando lo publiqué, pero como se explica en la respuesta de @ Yaroslov (excelente y correcta), este ya no es el caso: Codelizer ahora advierte y la comstackción de AoT fallará en las referencias a variables privadas en plantillas de componentes . Dicho esto, en un nivel conceptual, todo lo que sigue aquí sigue siendo válido, así que dejaré esta respuesta ya que parece haber sido útil.


Sí, esto es esperado.

Tenga en cuenta que private modificadores de acceso private y de otro tipo son constructos de Typecript, mientras que Component / controller / template son construcciones angulares de las que Typescript no sabe nada. Los modificadores de acceso controlan la visibilidad entre clases: hacer que un campo sea private impide que otras clases tengan acceso a él, pero las plantillas y los controladores son cosas que existen dentro de las clases.

Eso no es técnicamente cierto, pero (en lugar de entender cómo se relacionan las clases con los decodificadores y sus metadatos), podría ser útil pensarlo de esta manera, porque lo importante (en mi humilde opinión) es pasar de pensar en la plantilla y el controlador como algo separado las entidades a pensar en ellas como partes unificadas de la construcción componente: este es uno de los principales aspectos del modelo mental ng2.

Al pensarlo de esa manera, obviamente esperamos que private variables private en una clase de componente sean visibles en su plantilla, por la misma razón que esperamos que sean visibles en los métodos private en esa clase.

No, no deberías estar usando variables privadas en tus plantillas.

Aunque me gusta la respuesta de drewmoore y veo lógica conceptual perfecta en ella, en la implementación está mal. Las plantillas no existen dentro de las clases de componentes, pero fuera de ellas. Echa un vistazo a este repository para la prueba.

La única razón por la que funciona es porque la palabra clave private de TypeScript realmente no hace que el miembro sea privado. La comstackción Just-In-Time ocurre en un navegador en tiempo de ejecución y JS no tiene ningún concepto de miembros privados (¿todavía?). El crédito va para Sander Elias por ponerme en el camino correcto.

Con la ngc y Ahead-of-Time, obtendrá errores si intenta acceder a los miembros privados del componente desde la plantilla. MyComponent repository de demostración, cambia la MyComponent miembros de MyComponent a privada y obtendrás errores de comstackción cuando ngc . Aquí también está la respuesta específica para la comstackción Ahead-of-Time.

Aunque el ejemplo del código indica que la pregunta es sobre TypeScript, no tiene la etiqueta de mecanografía . Angular2 también está disponible para Dart y esta es una diferencia notable para Dart.

En Dart, la plantilla no puede hacer referencia a variables privadas de la clase de componente, porque Dart, en contraste con TypeScript, impide el acceso de miembros privados desde afuera.

Todavía recuerdo la sugerencia de @drewmoores de pensar en el componente y su plantilla como una unidad.

Actualización (TS) Parece que con la comstackción sin conexión, el acceso a las propiedades privadas será más limitado en Angular2 TS y https://github.com/angular/angular/issues/11422

Las variables privadas se pueden usar dentro de la plantilla del componente. Consulte la hoja de referencia de angular2 para obtener la guía: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

Puede encontrar una explicación más detallada sobre los miembros públicos / privados de las clases en texto typescript aquí: https://www.typescriptlang.org/docs/handbook/classes.html .

Todos los miembros por defecto son públicos. Se puede acceder a los miembros públicos desde fuera de la clase de componente junto con la instancia de clase. Pero se puede acceder a los miembros privados solo dentro de las funciones de los miembros de la clase.

Una solución alternativa podría ser el uso de variables privadas en el archivo ts y el uso de getters.

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

Este es un buen enfoque porque el archivo ts y html son independientes. Incluso si cambia el nombre de la variable _userName en el archivo ts, no tiene que hacer ningún cambio en el archivo de la plantilla.