Свойство X является частным и доступно только в классе xyzComponent.


102

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

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

После некоторого поиска я нашел этот блог, в котором объясняется проблема в "Свойстве контекста" разделе которое я не могу правильно понять, возможно, он дает вам хорошее представление о том, что происходит не так. в основном, когда мы делаем переменную частной, мы получаем «ОШИБКА: свойство является частным и доступно только внутри класса» . Я не понимаю, почему это происходит.

Пожалуйста, помогите нам, поскольку мы бьемся головой над этой проблемой последние пару дней.


1
вы пытались изменить собственность с частной на публичную?
Xin Meng

не могли бы вы поделиться содержимым ts-файла, которое вызывает ошибку?
Raj

Ответы:


143

Для данного компонента все его элементы (методы, свойства), к которым обращается его шаблон, должны быть общедоступными в сценарии компиляции AOT. Это связано с тем, что шаблон превращен в класс TS. Сгенерированный класс и компонент теперь являются двумя отдельными классами, и вы не можете получить доступ к частным членам кросс-класса.

Вкратце: вы не можете получить доступ к закрытым членам в своих шаблонах, если хотите использовать предварительную компиляцию.

Для лучшего объяснения https://github.com/angular/angular/issues/11422


но это было не в случае с более ранними версиями Angular, не так ли? Я начал получать эти ошибки после обновления до последней версии.
Эмиль

37

Может быть, еще один, еще более простой ответ:

Ребята, пожалуйста, не вызывайте приватные методы, поля или свойства из HTML :)


PS при компиляции *.tsкоды *.js, АОТ отбросов для подключения непубличных членов с HTML - шаблоном.

И «да», это приведет к сбою конвейера сборки: D


1
Или получите доступ к частным полям / свойствам!
JMK

@Arsen Khachaturyan Это смешно)
voodoo417

@JMK Я обновил сообщение в соответствии с вашим предложением, спасибо.
Арсен Хачатурян

@ voodoo417, смешно и верно;). Иногда слишком академический ответ может действительно поразить любого, и нам просто нужно быть как можно проще.
Арсен Хачатурян

1
@Arsen Khachaturyan Согласен, Arsen +++
voodoo417

17

Я получил это, когда объявил частные инъекции в конструкторе:

constructor(private service: SpecificObjectService) { }

И использовал их в шаблоне:

*ngFor="let pd of service.listSpecificObject "

Решение:

constructor(public service: SpecificObjectService) { }

16

Итак, я исправил эту проблему, я буду краток и прост. Чтобы исправить это, я внимательно прочитал этот блог . Как и в разделе « Свойство контекста ». Решение этой проблемы состоит в том, что не используйте и не создавайте частную переменную, если вы хотите использовать ее непосредственно в представлении, когда вы создаете свою сборку с AOT ( то есть, опережая время ) для производство.

*например *

// 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.чтобы указать на глобальный
LazerBanana

Что вы имеете в виду под локальным / глобальным? nameне является переменной, это свойство объекта. this.name = nameвызовет setter ( set name(v){}) для этого объекта. Это так легко проверить: blitz Maximum call stack size exceeded
vp_arth

6

Это работает для меня, ребята: просто измените сервис на публичный.

constructor(public service: SpecificObjectService) { }

Приложение работает в производстве !!


Таким образом, то же самое решение с менее подробным ответом, что и ответ @TiyebM выше.
Эш

1

хорошо, видите, это действительно простая проблема с 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.