If a variable is declared private
on a component class, should I be able to access it in the template of that component?
@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
}
We can access a private variable in a different class by putting that variable with in a Public method and calling that method from another class by creating object of that class. Example: using System; using System.
2. Private: The private declared properties and methods can be accessed only within the class definition itself. 3. Protected: Properties and methods can be accessed from inside the class or any other class extending the one that owns the property or the method which are declared as protected.
A template is a form of HTML that tells Angular how to render the component. Views are typically organized hierarchically, allowing you to modify or show and hide entire UI sections or pages as a unit. The template immediately associated with a component defines that component's host view.
UPD
Since Angular 14, it is possible to bind protected
components members in the template. This should partially address the concern of exposing internal state (which should only be accessible to the template) as the component's public API.
No, you shouldn't be using private variables in your templates.
While I like the drewmoore's answer and see perfect conceptual logic in it, implementationwise it's wrong. Templates do not exist within component classes, but outside of them. Take a look at this repo for the proof.
The only reason why it works is because TypeScript's private
keyword doesn't really make member private. Just-in-Time compilation happens in a browser at runtime and JS doesn't have any concept of private members (yet?). Credit goes to Sander Elias for putting me on the right track.
With ngc
and Ahead-of-Time compilation, you'll get errors if you try accessing private members of the component from template. Clone demonstration repo, change MyComponent
members' visibility to private and you will get compilation errors, when running ngc
. Here is also answer specific for Ahead-of-Time compilation.
Edit: This answer is now incorrect. There was no official guidance on the topic when I posted it, but as explained in @Yaroslov's (excellent, and correct) answer, this is no longer the case: Codelizer now warns and AoT compilation will fail on references to private variables in component templates. That said, on a conceptual level everything here remains valid, so I'll leave this answer up as it seems to have been helpful.
Yes, this is expected.
Keep in mind that private
and other access modifiers are Typescript constructs, whereas Component/controller/template are angular constructs that Typescript knows nothing about. Access modifiers control visibility between classes: Making a field private
prevents other classes from having access to it, but templates and controllers are things that exist within classes.
That's not technically true, but (in lieu of understanding how classes relate to decorators and their metadata), it might be helpful to think of it this way, because the important thing (IMHO) is to shift from thinking about template and controller as separate entities into thinking of them as unified parts of the Component construct - this is one of the major aspects of the ng2 mental model.
Thinking about it that way, obviously we expect private
variables on a component class to be visible in its template, for the same reason we expect them to be visible in the private
methods on that class.
Even though the code example indicates the question is about TypeScript it doesn't have the typescript tag. Angular2 is also available for Dart and this is a notable difference to Dart.
In Dart the template can't reference private variables of the component class, because Dart in contrast to TypeScript effectively prevents access of private members from outside.
I still back @drewmoores suggestion to think about component and it's template as one unit though.
Update (TS) It seems with offline compilation access to private properties will become more limited in Angular2 TS as well https://github.com/angular/angular/issues/11422
A workaround could be using private variables in ts file and using getters.
private _userName = "Test Name";
get userName() {
return this._userName;
}
This is a good approach because the ts file and the html remains independent. Even if you change the _userName variable name in ts file, you dont have to make any change in the template file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With