在学习本教程时,我遇到了一个奇怪的情况。
在将服务注入组件时,如果错过了访问修饰符,则会出现以下错误,但是将其添加为私有或公共运行会很好。
如果缺少访问修饰符,我们在Angular中是否没有任何默认范围?
export class UserDetailsComponent implements OnInit {
name="";
lastName="";
constructor(userService : UserServiceService) { }
ngOnInit() {
}
save(){
this.userService.saveUser();
}
}
类型'UserDetailsComponent'上不存在属性'userService'。
答案 0 :(得分:4)
如果为构造函数参数加上访问修饰符(private
,protected
或public
)或readonly
前缀,它将自动被“提升”为类属性在TypeScript中。这种构造称为构造器参数属性。
没有前缀,构造函数参数仅是方法参数,您必须从构造函数本身将其手动分配给已声明的类属性。
来自handbook:
通过在构造函数参数前面声明参数属性 使用辅助功能修饰符或
readonly
,或同时使用两者。使用private
对于参数属性,声明并初始化一个私有成员; 同样,public
,protected
和readonly
也是如此。
答案 1 :(得分:1)
Typescript为您提供了一种用于依赖项注入的常见模式的快捷方式。
您可以将其放在构造函数中:
this.userService = userService
并创建一个属性声明:
userService: UserService;
或者,您只需将“ public”放在ctor函数参数上,然后Typescript为您完成所有操作。 “私人”也一样。但是,如果尝试在模板中使用私有属性,则AOT可能会失败。
答案 2 :(得分:1)
已经提供的所有答案都非常清楚,并且具有良好的信息。因此,以一种简单的方式讲,这是正在发生的事情:
您的构造函数是一个函数。在任何编程语言中(到目前为止,我都遇到过),函数的参数仅存在于函数本身的范围内。因此,除非在构造函数中传递的参数的值已明确分配给类成员,否则该参数在整个类中均不可用(如Samuel J Matthew提供的第二段代码所示。
参数中的访问修饰符的作用是,它们指示Angular使用提供的访问修饰符创建与参数同名的类成员,并将其初始化为参数类型的实例。换句话说,该参数成为类成员/属性。如前所述,这称为参数属性,这是一个非常合适的名称。
Ken提供的文档非常有帮助。绝对值得一读。
答案 3 :(得分:0)
当您不为构造函数的参数提供任何访问说明符时,将发生问题,它将不会在类级别注册。相反,参数变量的范围仅限于构造函数,以便使其在整个类中可用我们给访问修饰符
以您的示例
export class UserDetailsComponent implements OnInit {
name="";
lastName="";
constructor(userService : UserServiceService) {
console.log(userService)
}
ngOnInit() {
}
save(){
this.userService.saveUser();
}
}
userService
仅在构造函数内部可用
如果将console.log(userService)
放在构造函数中,则可能会得到一些控制台输出。
如果您不想指定任何访问修饰符或想分配给另一个类变量,则可以像下面这样指定
export class UserDetailsComponent implements OnInit {
name="";
lastName="";
private _service
constructor(userService : UserServiceService) {
this._service = userService;
}
ngOnInit() {
}
save(){
this._service.saveUser();
}
}
在上面的代码中,我已将注入的userService
分配给另一个类成员_service