属性“ X”是私有的,只能在类“ xyzComponent”中访问


97

我正在尝试为该博客构建用于生产的 angular2应用程序。在ngc成功编译之后,当进行tsc编译时,它将生成以下图像中所示的错误:

在此处输入图片说明

搜索了一会儿后,我发现这个博客“上下文属性”部分解释了该问题,我无法正确理解该问题可能是因为它为您提供了一个很好的主意,那就是发生了什么问题。基本上,当我们将变量设为私有时,我们得到“错误:属性是私有的,并且只能在类中访问”。我不明白为什么会这样。

过去几天,我们一直在努力解决这个问题,请为我们提供帮助。


1
您是否尝试过将财产从私人更改为公共?
新孟

您能否分享ts文件内容抛出错误?
拉吉索尔·萨胡

Answers:


137

对于给定的组件,其模板访问的所有成员(方法,属性)在AOT编译方案中必须是公共的。这是由于将模板转换为TS类。现在,生成的类和组件是2个单独的类,您不能跨类访问私有成员。

简而言之:如果要使用提前编译,则无法访问模板中的私有成员。

为了更好的解释https://github.com/angular/angular/issues/11422


但这不是Angular的早期版本的情况,不是吗?升级到最新版本后,我已经开始收到这些错误。
batmaci

35

也许另一个更简单的答案是:

伙计们,请不要从HTML中调用私有方法,字段或属性:)


PS将*.ts代码编译为时*.jsAOT拒绝将非公共成员与HTML模板连接。

并且“是”,这将使您的构建管道失败:D


1
或访问私有字段/属性!
JMK

@Arsen Khachaturyan(很有趣)
voodoo417

@JMK我已经根据您的建议更新了帖子,谢谢。
Arsen Khachaturyan,

@ voodoo417,有趣而真实;)。有时候,过于学术化的回答确实会打动任何人的头脑,我们只需要尽可能地简化。
Arsen Khachaturyan

1
@Arsen Khachaturyan同意,Arsen +++
voodoo417

16

所以我解决了这个问题,我将使其简短而简单。为了解决这个问题,我深入阅读了此博客。如“ 上下文属性 ” 部分中所述,此问题的解决方案是,如果要在使用AOT创建构建(即Ahead Of Time)时直接在视图中使用它,则不要使用或创建私有变量。生产。

*例如 *

// component.ts
@Component({
  selector: 'third-party',
  template: `
    {{ _initials }}
  `
})
class ThirdPartyComponent {
  private _initials: string;
  private _name: string;

  @Input()
  set name(name: string) {
    if (name) {
      this._initials = name.split(' ').map(n => n[0]).join('. ') + '.';
      this._name = name;
    }
  }
}

输出: 属性'_initials'是私有的,只能在类'ThirdPartyComponent'中访问。

解:

更新private _initials: string;为简单_initials: string;

为此,Harish Gadiya为此提供了一些帮助。


不需要在_name那里使用,它可以与您使用的相同,也可以使用this.其他name局部变量this.name=name;
LazerBanana

@LazerBanana,但是this.name=nameset nameinf中。递归
vp_arth

@vp_arth吗?一是本地一是全球?我猜即使是同名2种不同的东西?这就是为什么您this.
习惯

您在本地/全球范围内是什么意思?name不是变量,它是对象属性。this.name = nameset name(v){}在该对象上触发setter()。测试起来非常容易:闪电战 Maximum call stack size exceeded
-vp_arth

16

当我在构造函数中声明私有可注入对象时,我得到了这个:

constructor(private service: SpecificObjectService) { }

并在模板中使用它们:

*ngFor="let pd of service.listSpecificObject "

解决方案是:

constructor(public service: SpecificObjectService) { }

6

这对我有用:只需将服务更改为公共即可。

constructor(public service: SpecificObjectService) { }

应用正在生产中!!


因此,与上述@TiyebM的答案相比,答案完全相同,而答案却不太详细。
Ash

0

好的,这确实是一个简单的javascript es6问题,如果您必须将数据类型设为私有,则可以简单地执行此操作

privateAccess(){
     return this.cannotAccessByInstanceButStillNeeded
}

0

如果您想在路由器中使用路由器,请将其公开。

例如:

<button 
   [routerLink]="['/login']"
   [queryParams]="{redirectTo: router.url}"
   translate="Please sign in to use this feature"
/>
import { Router } from '@angular/router'; 

constructor(
   public router: Router; // don't make it private
) {}

在Github CI向我发送警告邮件之前,我一直忽略了它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.