打字稿依赖注入public vs private

Vim*_*edi 25 typescript angular

注入服务与public和private之间有什么区别.我看到大多数示例在angular组件中使用private关键字.使用公众会有什么影响吗?例如

constructor(public carService: CarService) { }
Run Code Online (Sandbox Code Playgroud)

constructor(private carService: CarService) { }
Run Code Online (Sandbox Code Playgroud)

Deb*_*ahK 33

除了先前的答案之外......组件的模板也无法访问标记为私有的任何内容.(私有成员使用JIT时,例如在开发时使用AOT时,如用于生产被访问,但不是.)

因此,在您的模板中,您只能*ngIf='carService.isValid' 将注入的服务标记为public.

但实际上,最佳实践是将任何服务属性/方法包装在组件属性/方法中,并让模板绑定到/调用组件的属性或方法.

像这样的东西:

   get isValid(): boolean {
      return this.carService.isValid;
   }
Run Code Online (Sandbox Code Playgroud)

然后像这样访问它: *ngIf='isValid'

  • 以上是一个吸气剂.您不会将其称为方法,而是将其称为属性赋值.如果使用`*ngIf ='isValid'而不是'*ngIf ='isValid()',它应该可以工作 (6认同)
  • 您能否指出文档来支持您的声明“最佳实践是将任何服务属性/方法包装在组件属性/方法中,并让模板绑定到/调用组件的属性或方法”?听起来好像有很多不必要的工作。为什么不将服务设置为“公共只读”以保护其免受未来开发人员的编译,并避免编写所有额外的样板文件? (2认同)
  • 向 Angular GDE 社区提出了这个问题……有多种想法。(1) 使用编辑器工具完成的任何重构(重命名等)都不会在模板中找到实例。(2) 使用推荐的视图/模型方法和声明的 Observable 流,这不再是问题。(3) 对于一次性的,似乎还可以。 (2认同)
  • 只是为了添加和使用私有而不是公共的优势,如果您使用 VSCode,类中未使用的私有构造函数参数将以褪色显示,帮助您识别不再需要的注入。 (2认同)

apa*_*ina 6

例如,对于您有服务的情况:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})

export class CarService {

  constructor() { }

  public design = {
    "color": "blue"
  }
}
Run Code Online (Sandbox Code Playgroud)

在您将要实现服务的构造函数中

constructor(private carService: CarService) { }
Run Code Online (Sandbox Code Playgroud)

您可以使用正常方法返回服务

 getCarService() {
      return this.carService;
 }
Run Code Online (Sandbox Code Playgroud)

在你的模板中你可以做

<div>{{getCarService().design.color}}</div>
Run Code Online (Sandbox Code Playgroud)

  • 在模板中调用方法不是一个好主意 (6认同)
  • @Iznogood1 - 如上所述,控制台日志将向您显示发生了什么。原因是 OnChanges 必须在每次更改时运行该方法来确定值是否已更改,如果您在模板中使用 getter 或值,则它可以进行比较而无需再次运行该函数。 (3认同)
  • @Iznogood1,你不需要为此找到一些文档。只需将“console.log”放入您的方法中即可查看发生了什么 (2认同)

Com*_*ide 5

答案很简单:在不需要在当前类/组件之外使用私有变量时,必须创建私有变量,否则,应创建公共变量。还有一件事:您还可以使用私有变量,并通过称为getterssetters的特殊函数从外部访问它们。例如:

private _customValue: any;

set customValue(newValue: any): void {
  this._customValue = newValue;
}

get customValue(): any {
  return this._customValue;
}
Run Code Online (Sandbox Code Playgroud)

注意,这_customValue是私有的,但是您可以通过使用以下操作从类外部设置/获取该值customValue

classInstance.customValue = 'newValue';
console.log(classInstance.customValue);
Run Code Online (Sandbox Code Playgroud)

需要说的是setget在方法名称之前并不需要关键字,因此更需要澄清。