Angular 8: 将 utils 服务定义为单例并使用静态方法?
Angular 8: Define a utils service as singleton and with static methods?
我目前从Angular 8开始。现在我想编写一个包含util函数的服务("CoreService")。但我想知道我到底应该怎么做,以及不同选项的优点或缺点是什么:
- 我应该定义为单例吗?
- 我应该将函数定义为静态方法(由
CoreService.doSomething()
调用)还是将其定义为具有非静态方法的可注入 class(在构造函数中注入)?
也许其中一个选项对性能(内存?)有或多或少的影响。
非常感谢任何回答!
再见The_Unknown
好的,让我们解决 Angular 中的服务。让我们先直接了解一些细节。
创建服务的推荐方法是使用 CLI:
ng generate service foo/weather
这将在 src/app/foo/weather.service.ts
下创建一个新服务 - 以及一些测试框架。如果您检查这段代码,您会发现它看起来像这样:
@Injectable({
providedIn: 'root',
})
export class WeatherService {
constructor() { }
}
1.是否单身
现在看上面的 providedIn: 'root'
行。这样,您基本上是在说 Angular 应该在根级别提供此服务。在这种情况下,Angular 将创建一个单一的、共享的 WeatherService 实例,并将这个单一实例注入到任何需要它的组件中。此外,来自 Angular 文档:
Registering the provider in the @Injectable() metadata also allows Angular to optimize an app by removing the service from the compiled app if it isn't used.
所以这也可以为您节省一些带宽。
当然服务是供其他组件使用的。如果您决定在组件级别注册一个提供者,您将获得一个新的服务实例以及该组件的每个新实例。它将是这样的:
@Component({
selector: 'app-cities',
templateUrl: './cities.component.html',
providers: [ WeatherService ]
})
还有第三个 "level" 粒度 - 范围为一个模块 - 如果你想让你的服务实例可用于所有组件 但 只是在上述模块中:
@NgModule({
providers: [
WeatherService,
AnotherService
],
...
})
简而言之 - 您可以控制您想要的服务方式 - 是否单身 - 以及所有的影响。
2。静态或实例方法
在我看来这不是一个真正的问题。要走的路是使用实例方法。无论如何,这是通过 Angular 的依赖注入强制执行的。您将创建的组件将请求您的服务实例。 Angular 的 DI 将提供一个(单例或新的),您可以像使用任何其他实例化对象一样使用它:
@Injectable({
providedIn: 'root',
})
export class WeatherService {
getTodaysTemperature() { return 7; }
}
@Component({
... // omitted for simplicity
})
export class TemperatureComponent {
constructor(weatherService: WeatherService) {
this.temperature = weatherService.getTodaysTemperature();
}
}
所以只要确保你提供了相应的实例方法就可以了。测试也很好,因为您可以注入您的服务甚至模拟它。
我目前从Angular 8开始。现在我想编写一个包含util函数的服务("CoreService")。但我想知道我到底应该怎么做,以及不同选项的优点或缺点是什么:
- 我应该定义为单例吗?
- 我应该将函数定义为静态方法(由
CoreService.doSomething()
调用)还是将其定义为具有非静态方法的可注入 class(在构造函数中注入)?
也许其中一个选项对性能(内存?)有或多或少的影响。
非常感谢任何回答!
再见The_Unknown
好的,让我们解决 Angular 中的服务。让我们先直接了解一些细节。
创建服务的推荐方法是使用 CLI:
ng generate service foo/weather
这将在 src/app/foo/weather.service.ts
下创建一个新服务 - 以及一些测试框架。如果您检查这段代码,您会发现它看起来像这样:
@Injectable({
providedIn: 'root',
})
export class WeatherService {
constructor() { }
}
1.是否单身
现在看上面的 providedIn: 'root'
行。这样,您基本上是在说 Angular 应该在根级别提供此服务。在这种情况下,Angular 将创建一个单一的、共享的 WeatherService 实例,并将这个单一实例注入到任何需要它的组件中。此外,来自 Angular 文档:
Registering the provider in the @Injectable() metadata also allows Angular to optimize an app by removing the service from the compiled app if it isn't used.
所以这也可以为您节省一些带宽。
当然服务是供其他组件使用的。如果您决定在组件级别注册一个提供者,您将获得一个新的服务实例以及该组件的每个新实例。它将是这样的:
@Component({
selector: 'app-cities',
templateUrl: './cities.component.html',
providers: [ WeatherService ]
})
还有第三个 "level" 粒度 - 范围为一个模块 - 如果你想让你的服务实例可用于所有组件 但 只是在上述模块中:
@NgModule({
providers: [
WeatherService,
AnotherService
],
...
})
简而言之 - 您可以控制您想要的服务方式 - 是否单身 - 以及所有的影响。
2。静态或实例方法
在我看来这不是一个真正的问题。要走的路是使用实例方法。无论如何,这是通过 Angular 的依赖注入强制执行的。您将创建的组件将请求您的服务实例。 Angular 的 DI 将提供一个(单例或新的),您可以像使用任何其他实例化对象一样使用它:
@Injectable({
providedIn: 'root',
})
export class WeatherService {
getTodaysTemperature() { return 7; }
}
@Component({
... // omitted for simplicity
})
export class TemperatureComponent {
constructor(weatherService: WeatherService) {
this.temperature = weatherService.getTodaysTemperature();
}
}
所以只要确保你提供了相应的实例方法就可以了。测试也很好,因为您可以注入您的服务甚至模拟它。