Angular2 – le variabili private dovrebbero essere accessibili nel modello?

Se una variabile è dichiarata private su una class componente, dovrei essere in grado di accedervi nel modello di quel componente?

 @Component({ selector: 'my-app', template: ` 

{{title}}

Hello {{userName}}

// I am getting this name
`, }) export class App { public title = 'Angular 2'; private userName = "Test Name"; //declared as private }

Modifica: questa risposta è ora errata. Non c’era una guida ufficiale sull’argomento quando l’ho postato, ma come spiegato nella risposta di @ Yaroslov (eccellente e corretta), questo non è più il caso: Codelizer ora avvisa e la compilazione AoT fallirà sui riferimenti a variabili private nei modelli di componenti . Detto questo, a livello concettuale tutto qui rimane valido, quindi lascerò questa risposta come sembra essere stata utile.


Sì, è previsto.

Tieni presente che i modificatori di accesso private e di altro tipo sono costrutti Typescript, mentre Component / controller / template sono costrutti angolari di cui Typescript non sa nulla. I modificatori di accesso controllano la visibilità tra le classi: rendere un campo private impedisce ad altre classi di accedervi, ma template e controller sono cose che esistono all’interno delle classi.

Questo non è tecnicamente vero, ma (al posto di capire come le classi si riferiscono ai decoratori e ai loro metadati), potrebbe essere utile pensarlo in questo modo, perché la cosa importante (IMHO) è di passare dal pensare a template e controller come separati le quadro a considerarle come parti unificate del costrutto Componente: questo è uno degli aspetti principali del modello mentale ng2.

Pensandoci su questo, ovviamente ci aspettiamo che private variabili private su una class di componenti siano visibili nel suo modello, per la stessa ragione ci aspettiamo che siano visibili nei metodi private su quella class.

No, non dovresti usare variabili private nei tuoi modelli.

Mentre mi piace la risposta di Drewmoore e vedo la perfetta logica concettuale in essa, implementare è sbagliato. I modelli non esistono all’interno delle classi dei componenti, ma al di fuori di essi. Dai un’occhiata a questo repo per la dimostrazione.

L’unica ragione per cui funziona è perché la parola chiave private di TypeScript non rende davvero privato il membro. La compilazione Just-in-Time avviene in un browser in fase di esecuzione e JS non ha alcun concetto di membri privati ​​(ancora?). Il merito va a Sander Elias per avermi messo sulla strada giusta.

Con la ngc e Ahead-of-Time, riceverai errori se provi ad accedere ai membri privati ​​del componente dal modello. Clona dimostrazione repo, modifica la visibilità dei membri MyComponent in privato e otterrai errori di compilazione durante l’esecuzione di ngc . Qui è anche la risposta specifica per la compilazione Ahead-of-Time.

Anche se l’esempio di codice indica che la domanda riguarda TypeScript, non ha il tag typescript . Angular2 è disponibile anche per Dart e questa è una notevole differenza per Dart.

In Dart il modello non può fare riferimento a variabili private della class del componente, poiché Dart in contrasto con TypeScript impedisce efficacemente l’accesso di membri privati ​​dall’esterno.

Sono ancora tornato al suggerimento di @drewmoores di pensare al componente ed è il modello come una sola unità.

Aggiornamento (TS) Sembra che con l’accesso alla compilazione offline le proprietà private diventino più limitate anche in Angular2 TS https://github.com/angular/angular/issues/11422

Le variabili private possono essere utilizzate all’interno del modello di componente. Vedi il cheat sheet di angular2 per la guida: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

Una spiegazione più dettagliata sui membri pubblici / privati ​​delle classi in typescript può essere trovata qui: https://www.typescriptlang.org/docs/handbook/classs.html .

Tutti i membri per impostazione predefinita sono pubblici. È ansible accedere ai membri pubblici dall’esterno della class del componente insieme all’istanza di class. Ma ai membri privati ​​è ansible accedere solo all’interno delle funzioni dei membri della class.

Una soluzione alternativa potrebbe essere l’utilizzo di variabili private nel file ts e l’utilizzo di getter.

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

Questo è un buon approccio perché il file ts e l’html rimangono indipendenti. Anche se si modifica il nome della variabile _userName nel file ts, non è necessario apportare alcuna modifica nel file del modello.