Die Eigenschaft 'X' ist privat und nur innerhalb der Klasse 'xyzComponent' zugänglich.


96

Ich versuche, eine Angular2-Anwendung für die Produktion zu erstellen, für die ich diesem Blog folge . Nach meiner erfolgreichen ngc- Kompilierung, wenn die tsc-Kompilierung stattfindet, wird der folgende Fehler im Bild generiert:

Geben Sie hier die Bildbeschreibung ein

Nachdem ich eine Weile gesucht hatte, fand ich diesen Blog, der das Problem im Abschnitt "Die Kontexteigenschaft" erklärt, den ich nicht richtig verstehen kann. Vielleicht gibt er Ihnen eine gute Vorstellung davon, was falsch passiert. Wenn wir eine Variable privat machen, erhalten wir im Grunde "FEHLER: Eigenschaft ist privat und nur innerhalb der Klasse zugänglich" . Ich verstehe nicht, warum es kommt.

Bitte helfen Sie uns, während wir uns in den letzten Tagen mit diesem Problem beschäftigen.


1
Haben Sie versucht, die Immobilie von privat zu öffentlich zu ändern?
Xin Meng

Kannst du bitte den Inhalt der Datei teilen, der einen Fehler auslöst?
Rajkishor Sahu

Antworten:


136

Für eine bestimmte Komponente müssen alle Mitglieder (Methoden, Eigenschaften), auf die über ihre Vorlage zugegriffen wird, im AOT-Kompilierungsszenario öffentlich sein. Dies liegt daran, dass eine Vorlage in eine TS-Klasse umgewandelt wird. Eine generierte Klasse und eine Komponente sind jetzt zwei separate Klassen, und Sie können nicht klassenübergreifend auf private Mitglieder zugreifen.

Kurz gesagt: Sie können in Ihren Vorlagen nicht auf private Mitglieder zugreifen, wenn Sie die Kompilierung im Voraus verwenden möchten.

Zur besseren Erklärung https://github.com/angular/angular/issues/11422


aber das war nicht der Fall frühere Versionen von Angular, nicht wahr? Ich habe begonnen, diese Fehler nach dem Upgrade auf die neueste Version zu bekommen.
Batmaci

35

Vielleicht ist eine andere noch einfachere Antwort:

Leute, bitte ruft keine privaten Methoden, Felder oder Eigenschaften aus dem HTML auf :)


PS beim Kompilieren des *.tsCodes *.js, AOT Müll nicht-öffentliche Mitglieder mit dem verbinden , HTML - Vorlage.

Und "Ja" führt dazu, dass Ihre Build-Pipeline fehlschlägt: D.


1
Oder greifen Sie auf private Felder / Eigenschaften zu!
JMK

@Arsen Khachaturyan Es ist lustig)
voodoo417

@JMK Ich habe den Beitrag gemäß Ihrem Vorschlag aktualisiert, danke.
Arsen Khachaturyan

@ voodoo417, lustig und wahr;). Manchmal kann eine zu akademische Antwort wirklich jeden umhauen, und wir müssen einfach so einfach wie möglich sein.
Arsen Khachaturyan

1
@Arsen Khachaturyan Zustimmen, Arsen +++
voodoo417

16

Also habe ich dieses Problem behoben. Ich werde es kurz und einfach halten. Um dies zu beheben, habe ich diesen Blog gründlich gelesen . Wie im Abschnitt " Die Kontexteigenschaft " Die Lösung für dieses Problem besteht darin, dass Sie keine private Variable verwenden oder erstellen, wenn Sie sie direkt in der Ansicht verwenden möchten, wenn Sie Ihren Build mit AOT ( dh Ahead Of Time ) für erstellen Produktion.

*zum Beispiel *

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

Ausgabe: Die Eigenschaft '_initials' ist privat und nur innerhalb der Klasse 'ThirdPartyComponent' zugänglich.

Lösung:

Aktualisieren Sie dies private _initials: string;einfach_initials: string;

Für diese Antwort hilf mir Harish Gadiya , danke dafür.


müssen dort nicht verwendet _namewerden, es kann das gleiche sein, das Sie verwenden, this.und andere ist nameeine lokale Variablethis.name=name;
LazerBanana

@LazerBanana, aber this.name=namein der set nameist inf. Rekursion
vp_arth

@vp_arth? man ist lokal man ist global? sogar mit dem gleichen Namen 2 verschiedene Dinge, denke ich? Deshalb zeigst du this.auf die globale
LazerBanana

Was meinst du mit lokal / global? nameist nicht variabel, es ist Objekteigenschaft. this.name = namelöst setter ( set name(v){}) für dieses Objekt aus. So einfach zu testen: blitz Maximum call stack size exceeded
vp_arth

15

Ich habe dies erhalten, als ich private Injectables im Konstruktor deklariert habe:

constructor(private service: SpecificObjectService) { }

Und verwendet sie in der Vorlage:

*ngFor="let pd of service.listSpecificObject "

Die Lösung ist:

constructor(public service: SpecificObjectService) { }

5

Das funktioniert bei mir: Wechseln Sie einfach den Service in die Öffentlichkeit.

constructor(public service: SpecificObjectService) { }

App arbeitet in der Produktion !!


Also genau die gleiche Lösung mit einer weniger detaillierten Antwort als die Antwort von @ TiyebM oben.
Ash

0

ok, das ist wirklich ein einfaches Javascript es6-Problem. Wenn Sie den Datentyp privat halten müssen, können Sie dies einfach tun

privateAccess(){
     return this.cannotAccessByInstanceButStillNeeded
}

0

Wenn Sie den Router in der Ansicht verwenden möchten, machen Sie ihn bitte öffentlich.

Z.B:

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

Ich habe es übersehen, bis Github CI mir eine Warnmail schickte.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.