我应该在其构造函数中还是在 app.component 的 ngOnInit 方法中初始化 Angular 服务?
Posted
技术标签:
【中文标题】我应该在其构造函数中还是在 app.component 的 ngOnInit 方法中初始化 Angular 服务?【英文标题】:Should I initialise an Angular service in its constructor or in the ngOnInit method of the app.component? 【发布时间】:2020-10-02 02:58:16 【问题描述】:我是 Angular 的新手。我有一项服务需要订阅另一个服务提供的主题。如果这是一个组件,我会在组件的 ngOnInit 方法中创建订阅。不过,服务不需要 NgOnInit。我创建了一个初始化方法来创建订阅,但我不确定从哪里最好地调用它。我已经看到它做了两种方式:
1) 在服务构造函数中调用initialise方法
2) 将服务注入到 app.component 中,并在 app.component 的 ngOnInit 方法中调用服务初始化方法,例如
方法一:
export class MyService
constructor(private myRequiredService: RequiredService)
this.initialiseSubs();
initaliseSubs()
//code to set up subscriptions
方法二
export class MyService
constructor(private myRequiredService: RequiredService)
initaliseSubs()
//code to set up subscriptions
export class AppComponent implements OnInit
title = 'my-app';
constructor(private myService:MyService)
ngOnInit()
this.myService.initialiseSubs();
这两种方法似乎都有效,但我欢迎就哪种方法更可取提出建议。提前致谢。
【问题讨论】:
【参考方案1】:服务是您定义可观察对象的地方,例如getAllEmployees()
,组件是您使用这些服务的地方(将服务注入构造函数)。
export class MyService
constructor(private myRequiredService: RequiredService)
getAllEmployees():Observable<Employee[]>
// return Observables of type Employee[]
假设现在您有一个名为EmployeesList
的组件,它负责显示所有员工数据,首先,您需要将服务注入构造函数,然后您需要调用getAllEmployees
服务方法并订阅,以便获取数据。
export class EmployeesListimplements OnInit
private employees: Employee[];
constructor(private myService:MyService)
ngOnInit()
// it's better to do the subscription inside ngOnInit.
this.myService.getAllEmployees().subscribe(
employees =>
this.employees = employees;
);
基本上你应该这样做,但是为了更好的开发和更好的用户体验,我建议使用angular resolvers
,解析器基本上是可以附加到特定路由的方法,并且角度会在渲染组件之前调用它们,在这些内部方法您需要订阅getAllEmployees
服务方法并获取组件内部的值,使用解析器的主要目标是避免渲染视图然后等待从资源中获取数据。
但这被认为是一个高级主题,除非您要求我,否则我不会发布任何代码。
如果答案对您有帮助,请将其标记为正确。 万事如意!
编辑 在下面的 cmets 中讨论后,我了解到您有不同的后端可以根据当前路由进行通信,我会这样处理这种情况:
// inside the component
constructor(private router: Router)
ngOnInit()
// You need to find
this.myService.getAllEmployees(this.router.url).subscribe(
employees =>
this.employees = employees;
);
// inside the service file:
export class MyService
constructor(private myRequiredService: RequiredService)
getAllEmployees(URL: string):Observable<Employee[]>
// decide which back-end to connect with depending on the URL
switch(url)
case "example1":
URL = "url1";
break;
case "example2":
URL = "url2";
break;
// Connect to the resource using URL param
// return Observables of type Employee[]
【讨论】:
"最好在 ngOnInit 内部进行订阅。" - 你能详细说明为什么这是“更好”的方式吗? 非常感谢您的快速答复。你的例子是我 90% 的应用程序是如何工作的。我只是有一个不寻常的案例。该应用程序根据用于访问它的路线与不同的后端进行对话(网站有自己的网址和自己的后端)。站点服务根据 url 设置站点。身份验证服务将登录请求传递给相关的后端,如果站点发生变化,前端应该要求用户重新登录。因此,auth 服务需要订阅站点服务中的站点主题。因此需要初始化一个服务中对另一个服务中的主题的订阅。 @GeorgeKitching 欢迎您,我理解服务方法的后端 url 总是在变化,我认为您应该将 URL 作为参数传递给服务,而不是在服务内部订阅。因为您可以知道从组件内部调用了哪个路由,这取决于您可以决定调用哪个后端。 @PhilippMeissner 请在此处查看此答案:***.com/a/35763811/10121188 @FurqanS.Mahmoud。谢谢你。那可能行得通。我会考虑一下的。是否有任何理由避免在服务中订阅?它似乎有效,但我热衷于避免不可预见的陷阱。以上是关于我应该在其构造函数中还是在 app.component 的 ngOnInit 方法中初始化 Angular 服务?的主要内容,如果未能解决你的问题,请参考以下文章