La propiedad 'X' es privada y solo se puede acceder a ella dentro de la clase 'xyzComponent'


97

Estoy tratando de crear una aplicación angular2 para producción, por eso estoy siguiendo este blog . Después de mi compilación exitosa de ngc cuando se lleva a cabo la compilación de tsc , genera el siguiente error que se muestra en la imagen:

ingrese la descripción de la imagen aquí

Después de buscar por un tiempo, encontré este blog que explica el problema en la sección "La propiedad de contexto" que no puedo entender correctamente, puede ser que te dé una buena idea de lo que está sucediendo mal. básicamente, cuando hacemos una variable privada, obtenemos "ERROR: La propiedad es privada y solo se puede acceder a ella dentro de la clase" . No entiendo por qué viene.

Por favor ayúdenos ya que nos estamos dando golpes de cabeza con este problema durante los últimos días.


1
¿Ha intentado cambiar la propiedad de privada a pública?
Xin Meng

¿Puede compartir el contenido del archivo ts que arroja un error?
Rajkishor Sahu

Respuestas:


137

Para un componente dado, todos sus miembros (métodos, propiedades) a los que accede su plantilla deben ser públicos en el escenario de compilación AOT. Esto se debe al hecho de que una plantilla se convierte en una clase TS. Una clase generada y un componente son 2 clases separadas ahora y no puede acceder a miembros privados entre clases.

En resumen: no puede acceder a miembros privados en sus plantillas si desea utilizar la compilación anticipada.

Para una mejor explicación https://github.com/angular/angular/issues/11422


pero este no era el caso de las versiones anteriores de Angular, ¿no? Empecé a recibir esos errores después de actualizar a la versión más reciente.
batmaci

35

Quizás otra respuesta aún más simple es:

Chicos, no llamen a métodos, campos o propiedades privados desde el HTML :)


PD: al compilar el *.tscódigo *.js, AOT se niega a conectar miembros no públicos con la plantilla HTML .

Y "sí", esto hará que su canal de compilación falle: D


1
¡O acceda a campos / propiedades privados!
JMK

@Arsen Khachaturyan It`s funny)
voodoo417

@JMK He actualizado la publicación de acuerdo con su sugerencia, gracias.
Arsen Khachaturyan

@ voodoo417, divertido y verdadero;). A veces, una respuesta demasiado académica realmente puede sorprender a cualquiera, y solo necesitamos ser lo más simples posible.
Arsen Khachaturyan

1
@Arsen Khachaturyan De acuerdo, Arsen +++
voodoo417

16

Así que arreglé este problema, lo mantendré breve y simple. Para arreglar esto, leí este blog profundamente. Como en la sección " La propiedad de contexto " La solución para este problema es que no use o cree una variable privada si desea usarla en la vista directamente cuando esté creando su compilación con AOT ( es decir, Ahead Of Time ) para producción.

*por ejemplo *

// component.ts
@Component({
  selector: 'third-party',
  template: `
    {{ _initials }}
  `
})
class ThirdPartyComponent {
  private _initials: string;
  private _name: string;

  @Input()
  set name(name: string) {
    if (name) {
      this._initials = name.split(' ').map(n => n[0]).join('. ') + '.';
      this._name = name;
    }
  }
}

salida: la propiedad '_initials' es privada y solo se puede acceder a ella dentro de la clase 'ThirdPartyComponent'.

Solución:

actualiza esto private _initials: string;para simplemente_initials: string;

Para esta respuesta, Harish Gadiya me brindó algo de ayuda, así que gracias por eso.


no es necesario usarlo _nameallí, puede ser el mismo que usted usa this.y otro namees una variable localthis.name=name;
LazerBanana

@LazerBanana, pero this.name=nameen el set nameinf. recursividad
vp_arth

@vp_arth? uno es local uno es global? incluso con el mismo nombre 2 cosas diferentes, supongo? es por eso que usas this.para señalar el global
LazerBanana

¿Qué quieres decir con local / global? nameno es variable, es propiedad del objeto. this.name = nameactivará setter ( set name(v){}) en ese objeto. Tan fácil de probar: blitz Maximum call stack size exceeded
vp_arth

16

Obtuve esto cuando declaré inyectables privados en el constructor:

constructor(private service: SpecificObjectService) { }

Y los usó en la plantilla:

*ngFor="let pd of service.listSpecificObject "

La solucion es:

constructor(public service: SpecificObjectService) { }

6

Esto funciona para mí, chicos: simplemente cambie el servicio a público.

constructor(public service: SpecificObjectService) { }

App trabajando en producción !!


Entonces, exactamente la misma solución con una respuesta menos detallada que la respuesta de @ TiyebM anterior.
Ash

0

De acuerdo, esto es realmente un problema simple de javascript es6, si debe mantener el tipo de datos en privado, simplemente puede hacer esto

privateAccess(){
     return this.cannotAccessByInstanceButStillNeeded
}

0

Si desea utilizar el enrutador a la vista, hágalo público.

P.ej:

<button 
   [routerLink]="['/login']"
   [queryParams]="{redirectTo: router.url}"
   translate="Please sign in to use this feature"
/>
import { Router } from '@angular/router'; 

constructor(
   public router: Router; // don't make it private
) {}

Lo pasé por alto hasta que Github CI me envía un correo de advertencia.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.