web-dev-qa-db-ja.com

Angular2-テンプレートでプライベート変数にアクセスできるようにする必要がありますか?

コンポーネントクラスで変数がprivateとして宣言されている場合、そのコンポーネントのテンプレートで変数にアクセスできますか?

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>{{title}}</h2>
      <h2>Hello {{userName}}</h2> // I am getting this name
    </div>
  `,
})
export class App {
  public title = 'Angular 2';
  private userName = "Test Name"; //declared as private
}
114
3gwebtrain

いいえ、テンプレートでプライベート変数を使用しないでください。

私は drewmooreの答え が好きで、その中に完璧な概念的ロジックがありますが、実装上は間違っています。テンプレートはコンポーネントクラス内ではなく、外部に存在します。証拠については this repo をご覧ください。

それが機能する唯一の理由は、TypeScriptのprivateキーワードが実際にメンバーをプライベートにしないためです。ジャストインタイムコンパイルは実行時にブラウザで行われ、JSにはプライベートメンバーの概念はありません(まだですか?)。クレジットは Sander Elias が私を正しい方向に導いてくれたためです。

ngcおよびAhead-of-Timeコンパイルでは、テンプレートからコンポーネントのプライベートメンバーにアクセスしようとするとエラーが発生します。デモンストレーションリポジトリのクローンを作成し、MyComponentメンバーの可視性をprivateに変更すると、ngcの実行時にコンパイルエラーが発生します。これも answer Ahead-of-Timeコンパイルに固有です。

183
Yaroslav Admin

編集:この回答は現在正しくありません。トピックを投稿したとき、公式のガイダンスはありませんでしたが、@ Yaroslovの(優れた、正しい)回答で説明されているように、これは事実ではありません:Codelizer現在、警告が表示され、AoTコンパイルはコンポーネントテンプレートのプライベート変数への参照で失敗します。とはいえ、概念的なレベルではここのすべてが有効であるため、この回答は役立ったと思われるため、このままにしておきます。


はい、これは期待されています。

privateおよびその他のアクセス修飾子はTypeScript構造体であるのに対し、Component/controller/templateはTypeScriptが何も知らないangular構造体であることに注意してください。アクセス修飾子は可視性を制御しますbetweenクラス:フィールドprivateを作成すると、他のクラスがアクセスできなくなりますが、テンプレートとコントローラーは存在しますwithinクラス。

それは技術的には真実ではありませんが、(クラスがデコレータとそのメタデータにどのように関連するかを理解する代わりに)、このように考えるのが役立つかもしれません。構成要素の統一された部分としてそれらを考えるためのエンティティ-これはng2メンタルモデルの主要な側面の1つです。

そのように考えると、コンポーネントクラスのprivate変数がそのテンプレートで表示されることを期待することは明らかです。同じ理由で、そのクラスのprivateメソッドで表示されると期待するのと同じ理由です。

78
awqueous

コード例では、質問がTypeScriptに関するものであることを示していますが、 TypeScript タグはありません。 Angular2はDartでも使用でき、これはDartとの顕著な違いです。

Dartでは、テンプレートはコンポーネントクラスのプライベート変数を参照できませんなぜなら、DartはTypeScriptとは対照的に、外部からのプライベートメンバーのアクセスを効果的に防止するからです。

ただし、コンポーネントとそのテンプレートを1つのユニットとして考えるための@drewmooresの提案を引き続き支持しています。

更新(TS)オフラインコンパイルでは、Angular2 TSでもプライベートプロパティへのアクセスが制限されるようです https:// github。 com/angular/angular/issues/11422

14

プライベート変数は、コンポーネントのテンプレート内で使用できます。ガイドについては、angular2チートシートを参照してください: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

TypeScriptのクラスのpublic/privateメンバーに関する詳細な説明は、こちらにあります: https://www.typescriptlang.org/docs/handbook/classes.html

デフォルトでは、すべてのメンバーはパブリックです。パブリックメンバーは、クラスインスタンスとともにコンポーネントクラスの外部からアクセスできます。ただし、プライベートメンバーには、クラスメンバー関数内でのみアクセスできます。

3
anusreemn

回避策は、tsファイルでプライベート変数を使用し、ゲッターを使用することです。

private _userName = "Test Name";
get userName() {
  return this._userName;
}

Tsファイルとhtmlは独立したままなので、これは良いアプローチです。 tsファイルの_userName変数名を変更しても、テンプレートファイルに変更を加える必要はありません。

2
Franklin Pious

短い答えはいいえです。TSファイルから技術的に分離されているため、テンプレートからプライベートメンバーにアクセスすることはできません。

0
Ivens Applyrs