如果变量在组件类上声明为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
}
不,您不应该在模板中使用私有变量。
虽然我喜欢drewmoore's answer并且在其中看到完美的概念逻辑,但实施方式却是错误的。模板在组件类中不存在,但在它们之外。看看this repo的证据。
它工作的唯一原因是因为TypeScript的private
关键字并不真正使成员成为私有。实时编译在运行时在浏览器中进行,JS没有任何私有成员的概念(但是?)。归功于Sander Elias让我走上正轨。
使用ngc
和Ahead-of-Time编译,如果您尝试从模板访问组件的私有成员,则会出现错误。克隆演示回购,将MyComponent
成员的可见性更改为私有,当运行ngc
时,您将收到编译错误。这里也是针对Ahead-of-Time编译的answer。
编辑:此答案现在不正确。当我发布该主题时没有关于该主题的官方指导,但正如@ Yaroslov(优秀且正确)答案中所解释的那样,现在不再是这样了:Codelizer现在警告并且AoT编译将在组件模板中引用私有变量时失败。也就是说,从概念上讲,这里的一切都是有效的,所以我会把这个答案留下来,因为它似乎很有帮助。
是的,这是预料之中的。
请记住,private
和其他访问修饰符是Typescript构造,而Component / controller / template是Typescript一无所知的角度构造。访问修饰符控制类之间的可见性:创建字段private
可防止其他类访问它,但模板和控制器是类中存在的内容。
这在技术上并不正确,但(代替理解类与装饰器及其元数据的关系),以这种方式思考它可能会有所帮助,因为重要的是(恕我直言)从思考模板和控制器转变为单独的实体将它们视为Component构造的统一部分 - 这是ng2心理模型的主要方面之一。
以这种方式思考,显然我们期望组件类中的private
变量在其模板中可见,出于同样的原因,我们期望它们在该类的private
方法中可见。
尽管代码示例表明问题与TypeScript有关,但它没有typescript标记。 Angular2也适用于Dart,这与Dart有显着差异。
在Dart中,模板不能引用组件类的私有变量,因为与TypeScript相比,Dart有效地阻止了私有成员从外部访问。
我仍然支持@drewmoores建议考虑组件和它的模板作为一个单元。
更新(TS)似乎离线编译访问私有属性将在Angular2 TS以及https://github.com/angular/angular/issues/11422中变得更加有限
私有变量可以在组件模板中使用。请参阅angular2备忘单以获取指南:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter
关于打字稿中类的公共/私人成员的更详细解释可以在这里找到:https://www.typescriptlang.org/docs/handbook/classes.html。
默认情况下,所有成员都是Public。可以从组件类外部访问公共成员以及类实例。但是只能在类成员函数中访问私有成员。
解决方法可能是在ts文件中使用私有变量并使用getter。
private _userName = "Test Name";
get userName() {
return this._userName;
}
这是一个很好的方法,因为ts文件和html保持独立。即使您在ts文件中更改_userName变量名,也不必在模板文件中进行任何更改。
简短的回答是,你不应该能够从模板访问私有成员,因为它在技术上与TS文件分开。