Angular2 - 应该在模板中访问私有变量吗?

时间:2016-01-03 07:03:19

标签: typescript angular angular2-template

如果在组件类上声明变量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
}

7 个答案:

答案 0 :(得分:183)

不,您不应该在模板中使用私有变量。

虽然我喜欢drewmoore's answer并且在其中看到完美的概念逻辑,但实施方式却是错误的。模板在组件类中不存在,但在它们之外。请查看this repo以获取证据。

它工作的唯一原因是因为TypeScript的private关键字并不真正使成员成为私有。实时编译在运行时在浏览器中进行,JS没有任何私有成员的概念(但是?)。信用证转到Sander Elias,让我走上正轨。

使用ngc和Ahead-of-Time编译,如果您尝试从模板访问组件的私有成员,则会出现错误。克隆演示存储库,将MyComponent成员的可见性更改为私有,并且在运行ngc时会出现编译错误。这里还有answer特定的Ahead-of-Time编译。

答案 1 :(得分:77)

编辑:这个答案现在不正确。我发布时没有关于这个主题的官方指导,但正如@ Yaroslov(优秀,正确)答案中所解释的那样,不再是这种情况:Codelizer现在发出警告,AoT编译将在组件模板中引用私有变量时失败。也就是说,从概念上讲,这里的一切都是有效的,所以我会把这个答案留下来,因为它似乎很有帮助。

是的,这是预期的。

请记住,private和其他访问修饰符是Typescript构造,而Component / controller / template是Typescript一无所知的角度构造。访问修饰符控制类之间的可见性:使字段private阻止其他类访问它,但模板和控制器是内存在的内容类。

这在技术上并不正确,但是(代替了解类与装饰器及其元数据的关系),以这种方式思考它可能会有所帮助,因为重要的是(恕我直言)是从将模板和控制器视为单独的实体,将它们视为组件构造的统一部分 - 这是ng2心智模型的主要方面之一。

以这种方式思考,显然我们希望组件类中的private变量在其模板中可见,出于同样的原因,我们希望它们在该类的private方法中可见。

答案 2 :(得分:14)

即使代码示例表明问题与TypeScript有关,但它没有标记。 Angular2也适用于Dart,这与Dart有显着差异。

Dart 中,模板无法引用组件类的私有变量,因为与TypeScript相比,Dart会有效阻止私有成员从外部访问。

我仍然支持@drewmoores建议将组件及其模板视为一个单元。

更新(TS) 对于私有属性的离线编译似乎在Angular2 TS中也会变得更加有限https://github.com/angular/angular/issues/11422

答案 3 :(得分:3)

私有变量可以在组件的模板中使用。请参阅angular2备忘单以获取指南:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

有关打字稿中类的公共/私人成员的更详细说明,请访问:https://www.typescriptlang.org/docs/handbook/classes.html

默认情况下,所有成员都是公开的。可以从组件类外部访问公共成员以及类实例。但私有成员只能在类成员函数中访问。

答案 4 :(得分:2)

解决方法可能是在ts文件中使用私有变量并使用getter。

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

这是一个很好的方法,因为ts文件和html保持独立。即使您更改了ts文件中的_userName变量名,也无需在模板文件中进行任何更改。

答案 5 :(得分:0)

简短的回答是“不”,因为它在技术上与TS文件是分开的,所以您不应该从模板访问私有成员。

答案 6 :(得分:0)

在tsconfig.app.json中,如果在编译器选项中提供了“ fullTemplateTypeCheck”选项,则在项目构建时,您可以在项目的html文件中看到所有无效引用。

"angularCompilerOptions": {
"enableIvy": true,
"fullTemplateTypeCheck": true

}