【问题标题】:Should I initialise an Angular service in its constructor or in the ngOnInit method of the app.component?我应该在其构造函数中还是在 app.component 的 ngOnInit 方法中初始化 Angular 服务?
【发布时间】: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();

  }
}

这两种方法似乎都有效,但我欢迎就哪种方法更可取提出建议。提前致谢。

【问题讨论】:

    标签: angular service constructor initialization ngoninit


    【解决方案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 请在此处查看此答案:stackoverflow.com/a/35763811/10121188
    • @FurqanS.Mahmoud。谢谢你。那可能行得通。我会考虑一下的。是否有任何理由避免在服务中订阅?它似乎有效,但我热衷于避免不可预见的陷阱。
    猜你喜欢
    • 2018-06-23
    • 2011-07-01
    • 2016-09-29
    • 2011-08-08
    • 2022-11-12
    • 1970-01-01
    • 2018-07-27
    • 2012-02-04
    • 2011-01-26
    相关资源
    最近更新 更多