Властивість 'X' є приватною і доступна лише в класі 'xyzComponent'


97

Я намагаюся створити додаток angular2 для виробництва, для чого слідкую за цим блогом . Після моєї успішної компіляції ngc, коли відбувається компіляція tsc, вона генерує нижче помилку, показану на зображенні:

введіть тут опис зображення

Потрапивши на деякий час, я знайшов цей блог, який пояснює проблему в розділі "Властивість контексту", який я не можу зрозуміти належним чином, можливо, це дає вам гарну ідею про те, що відбувається неправильно. в основному, коли ми робимо змінну приватною, ми отримуємо "ПОМИЛКА: Властивість є приватною і доступна лише в класі" . Я не розумію, чому це відбувається.

Будь ласка, допоможіть нам, оскільки протягом останніх кількох днів ми б’ємося головою про цю проблему.


1
ви намагалися змінити власність з приватної на державну?
Xin Meng

Ви можете поділитися вмістом файлу TS, який викликає помилку?
Раджкішор Саху

Відповіді:


137

Для даного компонента всі його члени (методи, властивості), доступ до яких має його шаблон, повинні бути загальнодоступними у сценарії компіляції AOT. Це пов’язано з тим, що шаблон перетворюється на клас TS. Згенерований клас та компонент - це 2 окремі класи зараз, і ви не можете отримати доступ до перехресного класу приватних членів.

Коротше кажучи: ви не можете отримати доступ до приватних членів у своїх шаблонах, якщо хочете скористатися достроковою компіляцією.

Для кращого пояснення https://github.com/angular/angular/issues/11422


але це не стосувалося попередніх версій Angular, ні? я почав отримувати ці помилки після оновлення до останньої версії.
batmaci

35

Можливо, ще одна простіша відповідь:

Хлопці, будь ласка, не називайте приватні методи, поля чи властивості з HTML :)


PS під час компіляції *.tsкоду *.js, AOT відмовляється підключати непублічних учасників за допомогою HTML- шаблону.

І "так" це призведе до того, що ваш конвеєр збірки вийде з ладу: D


1
Або отримати доступ до приватних полів / властивостей!
JMK

@Arsen Khachaturyan Це смішно)
voodoo417

@JMK Я оновив допис відповідно до вашої пропозиції, дякую.
Арсен Хачатурян

@ voodoo417, смішно і правдиво;). Іноді занадто академічна відповідь може справді збити когось із розуму, і нам просто потрібно бути якомога простішими.
Арсен Хачатурян

1
@Arsen Khachaturyan Погоджуюсь, Arsen +++
voodoo417

16

Отже, я вирішив цю проблему, буду короткою і простою. Щоб це виправити, я глибоко прочитав цей блог . Як і в розділі " Властивість контексту " Рішення цієї проблеми полягає в тому, що не використовуйте та не створюйте приватну змінну, якщо ви хочете використовувати її у поданні безпосередньо, коли ви створюєте свою збірку за допомогою AOT ( тобто Ahead Of Time ) для виробництво.

*наприклад *

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

вихід: Властивість '_initials' є приватною і доступна лише в класі 'ThirdPartyComponent'.

Рішення:

оновити це private _initials: string;просто_initials: string;

Для цієї відповіді Харіш Гадія надає мені деяку допомогу, завдяки чому.


не потрібно _nameтам використовувати , це може бути так само, як і ви, this.та інша nameйого локальна зміннаthis.name=name;
LazerBanana

@LazerBanana, але this.name=nameв set nameінф. рекурсія
vp_arth

@vp_arth? один локальний один глобальний? навіть з однаковою назвою 2 різні речі, я думаю? ось чому ви this.
зазвичай

Що ви маєте на увазі під місцевим / глобальним? nameне є змінною, це властивість об’єкта. this.name = nameбуде запускати setter ( set name(v){}) на цьому об'єкті. Так легко це перевірити: blitz Maximum call stack size exceeded
vp_arth

16

Я отримав це, коли оголосив приватні ін’єкції в конструкторі:

constructor(private service: SpecificObjectService) { }

І використовував їх у шаблоні:

*ngFor="let pd of service.listSpecificObject "

Рішення:

constructor(public service: SpecificObjectService) { }

6

Це працює для мене, хлопці: просто змініть службу на публічну.

constructor(public service: SpecificObjectService) { }

Додаток, що працює у виробництві !!


Тож таке саме рішення з менш детальною відповіддю, як відповідь @ TiyebM вище.
Еш

0

добре бачимо, це насправді проста проблема javascript es6, якщо ви повинні тримати тип даних приватним, ви можете просто зробити це

privateAccess(){
     return this.cannotAccessByInstanceButStillNeeded
}

0

Якщо ви хочете використовувати маршрутизатор для огляду, будь ласка, опублікуйте його.

Наприклад:

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

Я пропустив це, поки Github CI не надіслав мені попереджувальний лист.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.