プロパティ 'X'はプライベートであり、クラス 'xyzComponent'内でのみアクセスできます


97

私はこのブログをフォローしているため、本番用のangular2アプリケーションを構築しようとしています。ngcのコンパイルが成功した後、tsc コンパイルが行われると、次の画像に示すエラーが生成されます。

ここに画像の説明を入力してください

しばらく検索したところ、「コンテキストプロパティ」セクションの問題を説明しているこのブログを見つけましたが、正しく理解できなかったため、何がおかしいのかよくわかります。基本的に、変数をプライベートにすると、「エラー:プロパティはプライベートであり、クラス内でのみアクセス可能」になります。なぜそれが来るのか理解できません。

過去数日間この問題に頭を悩ませているので、親切に助けてください。


1
プロパティをプライベートからパブリックに変更しようとしましたか?
Xin Meng

エラーが発生しているtsファイルのコンテンツを共有していただけますか?
Rajkishor Sahu

回答:


137

特定のコンポーネントについて、そのテンプレートによってアクセスされるすべてのメンバー(メソッド、プロパティ)は、AOTコンパイルシナリオでパブリックでなければなりません。これは、テンプレートがTSクラスに変換されるためです。生成されたクラスとコンポーネントは2つの別個のクラスになり、クラス間でプライベートメンバーにアクセスできなくなりました。

つまり、事前コンパイルを使用する場合は、テンプレートのプライベートメンバーにアクセスできません。

より良い説明のためにhttps://github.com/angular/angular/issues/11422


しかし、これはAngularの以前のバージョンではそうではありませんでしたか?最新バージョンにアップグレードした後、これらのエラーが発生し始めました。
batmaci

35

多分さらに簡単な答えは次のとおりです:

皆さん、HTMLからプライベートメソッド、フィールド、またはプロパティを呼び出さないでください:)


PSが*.tsコードをにコンパイルすると*.jsAOTは非公開メンバーをHTMLテンプレートに接続することを拒否します

そして「はい」これはあなたのビルドパイプラインを失敗させるでしょう:D


1
またはプライベートフィールド/プロパティにアクセスします!
JMK 2019年

@Arsen Khachaturyan It`s funny)
voodoo417

@JMK私はあなたの提案に従って投稿を更新しました、ありがとう。
Arsen Khachaturyan

@ voodoo417、おかしくて本当;)。時々、あまりにも学術的な答えは本当に誰かの心を吹き飛ばすことができます、そして私たちはできるだけ単純にする必要があります。
Arsen Khachaturyan

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;

この回答に対して、Harish Gadiyaは私にいくつかの助けを提供します。


ここで使用する必要は_nameありません。ローカル変数を使用する場合this.と同じにすることができnameますthis.name=name;
LazerBanana

@LazerBanana、しかしthis.name=namein set nameはinfです。再帰
vp_arth

@vp_arth?1つはローカル、1つはグローバルですか。同じ名前でも2つ違うと思う?それthis.が、
あなた

ローカル/グローバルとはどういう意味ですか?name変数ではなく、オブジェクトプロパティです。そのオブジェクトでthis.name = namesetter(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から警告メールが届くまで見落としました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.