Angular2 - ¿deben ser accesibles las variables privadas en la plantilla?


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

@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
}
Author: drewmoore, 2016-01-03

5 answers

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


Sí, esto es previsto.

Tenga en cuenta que private y otros modificadores de acceso son construcciones de Typescript, mientras que Componente/controlador/plantilla son construcciones angulares de las que Typescript no sabe nada. Los modificadores de acceso controlan la visibilidad entre las clases: Hacer un campo private evita 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 las clases se relacionan con los decoradores 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 entidades separadas a pensar en ellos como partes unificadas de la construcción de Componentes - este es uno de los aspectos principales del modelo mental ng2.

Pensándolo de esa manera, obviamente esperamos que las variables private en una clase de componente sean visibles en su plantilla, por la misma razón que esperamos que ser visible en los métodos private de esa clase.

 67
Author: drewmoore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-16 00:39:42

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

Aunque me gusta la respuesta de drewmoore y veo una lógica conceptual perfecta en ella, en cuanto a la implementación está mal. Las plantillas no existen dentro de las clases de componentes, sino fuera de ellas. Echa un vistazo a este repositorio 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 compilació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 es para Sander Elias por ponerme en el camino correcto.

Con ngc y compilación anticipada, obtendrás errores si intentas acceder a miembros privados del componente desde template. Clone el repositorio de demostración, cambie la visibilidad de los miembros MyComponent a privada y obtendrá errores de compilación cuando ejecute ngc. Aquí también está la respuesta específica para la compilación anticipada.

 144
Author: Yaroslav Admin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:05

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

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

Todavía respaldo la sugerencia de @ drewmoores de pensar en el componente y es plantilla como una unidad sin embargo.

Update (TS) Parece que con la compilación fuera de línea el acceso a las propiedades privadas también se verá más limitado en Angular2 TS https://github.com/angular/angular/issues/11422

 13
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-08 06:15:36

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

Una explicación más detallada sobre los miembros públicos/privados de las clases en typescript se puede encontrar 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 del componente class junto con la class-instance. Pero solo se puede acceder a los miembros privados dentro de las funciones miembro de la clase.

 2
Author: anusreemn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-23 07:54:33

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 el html permanecen 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 plantilla.

 1
Author: Franklin Pious,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-27 05:43:44