A propriedade 'X' é privada e acessível apenas dentro da classe 'xyzComponent'

97

Estou tentando construir um aplicativo angular2 para produção para isso, estou acompanhando este blog . Após minha compilação bem-sucedida do ngc, quando a compilação tsc ocorre, ele gera o erro abaixo mostrado na imagem:

insira a descrição da imagem aqui

Depois de pesquisar por um tempo encontrei este blog que explica o problema na seção "A propriedade do contexto" que não estou conseguindo entender direito, pode dar uma boa ideia para você do que está acontecendo de errado. basicamente, quando tornamos uma variável privada, obtemos "ERROR: a propriedade é privada e acessível apenas dentro da classe" . Não estou entendendo por que isso está vindo.

Por favor, ajude-nos, pois estamos batendo de cabeça neste problema nos últimos dias.

Sumit Khanduri
fonte
1
você já tentou mudar a propriedade de privada para pública?
Xin Meng,
você pode compartilhar o conteúdo do arquivo ts que está gerando um erro?
Rajkishor Sahu

Respostas:

137

Para um determinado componente, todos os seus membros (métodos, propriedades) acessados ​​por seu modelo devem ser públicos no cenário de compilação AOT. Isso se deve ao fato de um template ser transformado em uma classe TS. Uma classe gerada e um componente são duas classes separadas agora e você não pode acessar membros privados entre classes.

Resumindo: você não pode acessar membros privados em seus modelos se quiser usar a compilação antecipada.

Para melhor explicação https://github.com/angular/angular/issues/11422

harish gadiya
fonte
mas não era esse o caso das versões anteriores do Angular, não? Comecei a receber esses erros após atualizar para a versão mais recente.
batmaci
35

Talvez outra resposta ainda mais simples seja:

Pessoal, por favor, não chame métodos privados, campos ou propriedades do HTML :)


PS ao compilar o *.tscódigo *.js, AOT se recusa a conectar membros não públicos com o modelo HTML .

E "sim", isso fará com que seu pipeline de construção falhe: D

Arsen Khachaturyan
fonte
1
Ou acesse campos / propriedades privadas!
JMK
@Arsen Khachaturyan It`s funny)
voodoo417
@JMK Eu atualizei o post de acordo com sua sugestão, obrigado.
Arsen Khachaturyan
@ voodoo417, engraçado e verdadeiro;). Às vezes, uma resposta muito acadêmica pode realmente explodir qualquer pessoa, e só precisamos ser o mais simples possível.
Arsen Khachaturyan
1
@Arsen Khachaturyan Agree, Arsen +++
voodoo417
16

Então, resolvi esse problema e vou mantê-lo curto e simples. Para corrigir isso, li este blog profundamente. Como na seção " A propriedade do contexto " A solução para este problema é que não use ou crie uma variável privada se quiser usá-la na visualização diretamente quando estiver criando sua construção com AOT ( ou seja, Ahead Of Time ) para Produção.

*por exemplo *

// 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;
    }
  }
}

saída: a propriedade '_initials' é privada e acessível apenas na classe 'ThirdPartyComponent'.

Solução:

atualize isso private _initials: string;para simplesmente_initials: string;

Para esta resposta, Harish Gadiya me deu alguma ajuda, então obrigado por isso.

Sumit Khanduri
fonte
não precisa usar _namelá, pode ser o mesmo que você está usando this.e outra nameé uma variável localthis.name=name;
LazerBanana
@LazerBanana, mas this.name=nameno set nameé inf. recursão
vp_arth
@vp_arth? um é local outro é global? mesmo com o mesmo nome 2 coisas diferentes, não é? é por isso que você this.
costuma
O que você quer dizer com local / global? namenão é variável, é propriedade do objeto. this.name = nameirá acionar setter ( set name(v){}) naquele objeto. Tão fácil de testar: blitz Maximum call stack size exceeded
vp_arth
16

Eu entendi quando declarei os injetáveis ​​privados no construtor:

constructor(private service: SpecificObjectService) { }

E os usei no modelo:

*ngFor="let pd of service.listSpecificObject "

A solução é:

constructor(public service: SpecificObjectService) { }
TiyebM
fonte
6

Isso funciona para mim: basta mudar o serviço para público.

constructor(public service: SpecificObjectService) { }

App funcionando em produção !!

Carlos Valdes
fonte
Portanto, exatamente a mesma solução com uma resposta menos detalhada que a resposta de @TiyebM acima.
Ash
0

ok veja que este é realmente um problema simples de javascript es6, se você deve manter o tipo de dados privado, você pode simplesmente fazer isso

privateAccess(){
     return this.cannotAccessByInstanceButStillNeeded
}
MIchael Odumosu
fonte
0

Se você quiser usar o roteador em vista, torne-o público.

Por exemplo:

<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
) {}

Eu esqueci até que o Github CI me enviou um e-mail de aviso.

bravemaster
fonte